You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by jo...@apache.org on 2014/01/13 18:44:44 UTC
[1/3] git commit: [#6484] ticket:492 Move mediawiki import script to
separate repo
Updated Branches:
refs/heads/master 0ca218aba -> 491fbbf18
[#6484] ticket:492 Move mediawiki import script to separate repo
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/6d00c66d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/6d00c66d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/6d00c66d
Branch: refs/heads/master
Commit: 6d00c66d2b840c0d993f414df50ec87d2c0789d1
Parents: 0ca218a
Author: Igor Bondarenko <je...@gmail.com>
Authored: Mon Dec 30 12:47:20 2013 +0200
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Mon Jan 13 17:42:50 2014 +0000
----------------------------------------------------------------------
.../forgewiki/scripts/wiki2markdown/__init__.py | 18 -
.../scripts/wiki2markdown/extractors.py | 192 -----------
.../forgewiki/scripts/wiki2markdown/loaders.py | 201 -----------
.../scripts/wiki2markdown/wiki2markdown.py | 132 --------
ForgeWiki/forgewiki/tests/test_wiki2markdown.py | 329 -------------------
ForgeWiki/setup.py | 3 -
6 files changed, 875 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6d00c66d/ForgeWiki/forgewiki/scripts/wiki2markdown/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/scripts/wiki2markdown/__init__.py b/ForgeWiki/forgewiki/scripts/wiki2markdown/__init__.py
deleted file mode 100644
index f60b66d..0000000
--- a/ForgeWiki/forgewiki/scripts/wiki2markdown/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-from wiki2markdown import Wiki2Markdown
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6d00c66d/ForgeWiki/forgewiki/scripts/wiki2markdown/extractors.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/scripts/wiki2markdown/extractors.py b/ForgeWiki/forgewiki/scripts/wiki2markdown/extractors.py
deleted file mode 100644
index b70672c..0000000
--- a/ForgeWiki/forgewiki/scripts/wiki2markdown/extractors.py
+++ /dev/null
@@ -1,192 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-import logging
-import os
-import shutil
-import json
-import hashlib
-
-log = logging.getLogger(__name__)
-
-
-class MediawikiExtractor(object):
-
- """Base class for MediaWiki data provider"""
-
- def __init__(self, options):
- self.options = options
- if os.path.exists(self.options.dump_dir):
- # clear dump_dir before extraction (there may be an old data)
- shutil.rmtree(self.options.dump_dir)
- os.makedirs(self.options.dump_dir)
-
- def extract(self):
- """Extract pages with history, attachments, talk-pages, etc"""
- raise NotImplementedError("subclass must override this")
-
-
-class MySQLExtractor(MediawikiExtractor):
-
- """Extract MediaWiki data to json.
-
- Use connection to MySQL database as a data source.
- """
-
- def __init__(self, options):
- super(MySQLExtractor, self).__init__(options)
- self._connection = None
- self.db_options = {
- 'host': self.options.host or 'localhost',
- 'user': self.options.user,
- 'passwd': self.options.password,
- 'db': self.options.db_name,
- 'port': self.options.port or 3306
- }
-
- def connection(self):
- try:
- import MySQLdb
- except ImportError:
- raise ImportError(
- 'GPL library MySQL-python is required for this operation')
-
- if not self._connection:
- self._connection = MySQLdb.connect(**self.db_options)
- return self._connection
-
- def _save(self, content, *paths):
- """Save json to file in local filesystem"""
- out_file = os.path.join(self.options.dump_dir, *paths)
- if not os.path.exists(os.path.dirname(out_file)):
- os.makedirs(os.path.dirname(out_file))
- with open(out_file, 'w') as out:
- out.write(content.encode('utf-8'))
-
- def _save_attachment(self, filepath, *paths):
- """Save attachment in dump directory.
-
- Copy from mediawiki dump directory to our internal dump directory.
-
- args:
- filepath - path to attachment in mediawiki dump.
- *paths - path to internal dump directory.
- """
- out_dir = os.path.join(self.options.dump_dir, *paths)
- if not os.path.exists(out_dir):
- os.makedirs(out_dir)
- shutil.copy(filepath, out_dir)
-
- def _pages(self):
- """Yield page_data for next wiki page"""
- c = self.connection().cursor()
- c.execute('select page.page_id, page.page_title '
- 'from page where page.page_namespace = 0')
- for row in c:
- _id, title = row
- page_data = {
- 'page_id': _id,
- 'title': title,
- }
- yield page_data
-
- def _history(self, page_id):
- """Yield page_data for next revision of wiki page"""
- c = self.connection().cursor()
- c.execute('select revision.rev_timestamp, text.old_text, '
- 'revision.rev_user_text '
- 'from revision '
- 'left join text on revision.rev_text_id = text.old_id '
- 'where revision.rev_page = %s', page_id)
- for row in c:
- timestamp, text, username = row
- page_data = {
- 'timestamp': timestamp,
- 'text': text or '',
- 'username': username
- }
- yield page_data
-
- def _talk(self, page_title):
- """Return page_data for talk page with `page_title` title"""
- c = self.connection().cursor()
- query_attrs = (page_title, 1) # page_namespace == 1 - talk pages
- c.execute('select text.old_text, revision.rev_timestamp, '
- 'revision.rev_user_text '
- 'from page '
- 'left join revision on revision.rev_id = page.page_latest '
- 'left join text on text.old_id = revision.rev_text_id '
- 'where page.page_title = %s and page.page_namespace = %s '
- 'limit 1', query_attrs)
-
- row = c.fetchone()
- if row:
- text, timestamp, username = row
- return {'text': text, 'timestamp': timestamp, 'username': username}
-
- def _attachments(self, page_id):
- """Yield path to next file attached to wiki page"""
- c = self.connection().cursor()
- c.execute('select il_to from imagelinks '
- 'where il_from = %s' % page_id)
- for row in c:
- name = row[0]
- # mediawiki stores attachmets in subdirectories
- # based on md5-hash of filename
- # so we need to build path to file as follows
- md5 = hashlib.md5(name).hexdigest()
- path = os.path.join(self.options.attachments_dir,
- md5[:1], md5[:2], name)
- if os.path.isfile(path):
- yield path
-
- def extract(self):
- self.extract_pages()
-
- def extract_pages(self):
- log.info('Extracting pages...')
- for page in self._pages():
- self.extract_history(page)
- self.extract_talk(page)
- self.extract_attachments(page)
- log.info('Extracting pages done')
-
- def extract_history(self, page):
- page_id = page['page_id']
- for page_data in self._history(page_id):
- page_data.update(page)
- self._save(json.dumps(page_data), 'pages', str(page_id),
- 'history', str(page_data['timestamp']) + '.json')
- log.info('Extracted history for page %s (%s)', page_id, page['title'])
-
- def extract_talk(self, page):
- page_id = page['page_id']
- talk_page_data = self._talk(page['title'])
- if talk_page_data:
- self._save(json.dumps(talk_page_data), 'pages', str(page_id),
- 'discussion.json')
- log.info('Extracted talk for page %s (%s)', page_id, page['title'])
- else:
- log.info('No talk for page %s (%s)', page_id, page['title'])
-
- def extract_attachments(self, page):
- page_id = page['page_id']
- for filepath in self._attachments(page_id):
- self._save_attachment(filepath, 'pages', str(page_id),
- 'attachments')
- log.info('Extracted attachments for page %s (%s)',
- page_id, page['title'])
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6d00c66d/ForgeWiki/forgewiki/scripts/wiki2markdown/loaders.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/scripts/wiki2markdown/loaders.py b/ForgeWiki/forgewiki/scripts/wiki2markdown/loaders.py
deleted file mode 100644
index a3e1e29..0000000
--- a/ForgeWiki/forgewiki/scripts/wiki2markdown/loaders.py
+++ /dev/null
@@ -1,201 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-import logging
-import os
-import json
-import datetime
-from pylons import tmpl_context as c
-from ming.orm.ormsession import ThreadLocalORMSession
-
-from allura import model as M
-from forgewiki import model as WM
-from forgewiki.converters import mediawiki2markdown
-from forgewiki.converters import mediawiki_internal_links2markdown
-from allura.lib import helpers as h
-from allura.lib import utils
-from allura.model.session import artifact_orm_session
-
-log = logging.getLogger(__name__)
-
-
-class MediawikiLoader(object):
-
- """Load MediaWiki data from json to Allura wiki tool"""
- TIMESTAMP_FMT = '%Y%m%d%H%M%S'
-
- def __init__(self, options):
- self.options = options
- self.nbhd = M.Neighborhood.query.get(name=options.nbhd)
- if not self.nbhd:
- raise ValueError("Can't find neighborhood with name %s"
- % options.nbhd)
- self.project = M.Project.query.get(shortname=options.project,
- neighborhood_id=self.nbhd._id)
- if not self.project:
- raise ValueError("Can't find project with shortname %s "
- "and neighborhood_id %s"
- % (options.project, self.nbhd._id))
-
- self.wiki = self.project.app_instance('wiki')
- if not self.wiki:
- raise ValueError("Can't find wiki app in given project")
-
- h.set_context(self.project.shortname, 'wiki', neighborhood=self.nbhd)
-
- def load(self):
- try:
- self.project.notifications_disabled = True
- artifact_orm_session._get().skip_mod_date = True
- self.load_pages()
- ThreadLocalORMSession.flush_all()
- log.info('Loading wiki done')
- finally:
- self.project.notifications_disabled = False
- artifact_orm_session._get().skip_mod_date = False
-
- def _pages(self):
- """Yield path to page dump directory for next wiki page"""
- pages_dir = os.path.join(self.options.dump_dir, 'pages')
- pages = []
- if not os.path.isdir(pages_dir):
- return
- pages = os.listdir(pages_dir)
- for directory in pages:
- dir_path = os.path.join(pages_dir, directory)
- if os.path.isdir(dir_path):
- yield dir_path
-
- def _history(self, page_dir):
- """Yield page_data for next wiki page in edit history"""
- page_dir = os.path.join(page_dir, 'history')
- if not os.path.isdir(page_dir):
- return
- pages = os.listdir(page_dir)
- pages.sort() # ensure that history in right order
- for page in pages:
- fn = os.path.join(page_dir, page)
- try:
- with open(fn, 'r') as pages_file:
- page_data = json.load(pages_file)
- except IOError, e:
- log.error("Can't open file: %s", str(e))
- raise
- except ValueError, e:
- log.error("Can't load data from file %s: %s", fn, str(e))
- raise
- yield page_data
-
- def _talk(self, page_dir):
- """Return talk data from json dump"""
- filename = os.path.join(page_dir, 'discussion.json')
- if not os.path.isfile(filename):
- return
- try:
- with open(filename, 'r') as talk_file:
- talk_data = json.load(talk_file)
- except IOError, e:
- log.error("Can't open file: %s", str(e))
- raise
- except ValueError, e:
- log.error("Can't load data from file %s: %s", filename, str(e))
- raise
- return talk_data
-
- def _attachments(self, page_dir):
- """Yield (filename, full path) to next attachment for given page."""
- attachments_dir = os.path.join(page_dir, 'attachments')
- if not os.path.isdir(attachments_dir):
- return
- attachments = os.listdir(attachments_dir)
- for filename in attachments:
- yield filename, os.path.join(attachments_dir, filename)
-
- def load_pages(self):
- """Load pages with edit history from json to Allura wiki tool"""
- log.info('Loading pages into allura...')
- for page_dir in self._pages():
- for page in self._history(page_dir):
- p = WM.Page.upsert(page['title'])
- p.viewable_by = ['all']
- p.text = mediawiki_internal_links2markdown(
- mediawiki2markdown(page['text']),
- page['title'])
- timestamp = datetime.datetime.strptime(page['timestamp'],
- self.TIMESTAMP_FMT)
- p.mod_date = timestamp
- c.user = (M.User.query.get(username=page['username'].lower())
- or M.User.anonymous())
- ss = p.commit()
- ss.mod_date = ss.timestamp = timestamp
-
- # set home to main page
- if page['title'] == 'Main_Page':
- gl = WM.Globals.query.get(app_config_id=self.wiki.config._id)
- if gl is not None:
- gl.root = page['title']
- log.info('Loaded history of page %s (%s)',
- page['page_id'], page['title'])
-
- self.load_talk(page_dir, page['title'])
- self.load_attachments(page_dir, page['title'])
-
- def load_talk(self, page_dir, page_title):
- """Load talk for page.
-
- page_dir - path to directory with page dump.
- page_title - page title in Allura Wiki
- """
- talk_data = self._talk(page_dir)
- if not talk_data:
- return
- text = mediawiki2markdown(talk_data['text'])
- page = WM.Page.query.get(app_config_id=self.wiki.config._id,
- title=page_title)
- if not page:
- return
- thread = M.Thread.query.get(ref_id=page.index_id())
- if not thread:
- return
- timestamp = datetime.datetime.strptime(talk_data['timestamp'],
- self.TIMESTAMP_FMT)
- c.user = (M.User.query.get(username=talk_data['username'].lower())
- or M.User.anonymous())
- thread.add_post(
- text=text,
- discussion_id=thread.discussion_id,
- thread_id=thread._id,
- timestamp=timestamp,
- ignore_security=True)
- log.info('Loaded talk for page %s', page_title)
-
- def load_attachments(self, page_dir, page_title):
- """Load attachments for page.
-
- page_dir - path to directory with page dump.
- """
- page = WM.Page.query.get(app_config_id=self.wiki.config._id,
- title=page_title)
- for filename, path in self._attachments(page_dir):
- try:
- with open(path) as fp:
- page.attach(filename, fp,
- content_type=utils.guess_mime_type(filename))
- except IOError, e:
- log.error("Can't open file: %s", str(e))
- raise
- log.info('Loaded attachments for page %s.', page_title)
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6d00c66d/ForgeWiki/forgewiki/scripts/wiki2markdown/wiki2markdown.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/scripts/wiki2markdown/wiki2markdown.py b/ForgeWiki/forgewiki/scripts/wiki2markdown/wiki2markdown.py
deleted file mode 100644
index 8a6e79e..0000000
--- a/ForgeWiki/forgewiki/scripts/wiki2markdown/wiki2markdown.py
+++ /dev/null
@@ -1,132 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-import argparse
-import logging
-import shutil
-import tempfile
-
-from tg import config
-
-from allura.lib import helpers as h
-from allura.scripts import ScriptTask
-
-from forgewiki.scripts.wiki2markdown.extractors import MySQLExtractor
-from forgewiki.scripts.wiki2markdown.loaders import MediawikiLoader
-
-log = logging.getLogger(__name__)
-
-
-class Wiki2Markdown(ScriptTask):
-
- """Import MediaWiki to Allura Wiki tool"""
- @classmethod
- def parser(cls):
- parser = argparse.ArgumentParser(description='Import wiki from'
- 'mediawiki-dump to allura wiki')
- parser.add_argument('-e', '--extract-only', action='store_true',
- dest='extract',
- help='Store data from the mediawiki-dump '
- 'on the local filesystem; not load into Allura')
- parser.add_argument(
- '-l', '--load-only', action='store_true', dest='load',
- help='Load into Allura previously-extracted data')
- parser.add_argument('-d', '--dump-dir', dest='dump_dir', default='',
- help='Directory for dump files')
- parser.add_argument('-n', '--neighborhood', dest='nbhd', default='',
- help='Neighborhood name to load data')
- parser.add_argument('-p', '--project', dest='project', default='',
- help='Project shortname to load data into')
- parser.add_argument('-a', '--attachments-dir', dest='attachments_dir',
- help='Path to directory with mediawiki attachments dump',
- default='')
- parser.add_argument('--db_config_prefix', dest='db_config_prefix',
- help='Key prefix (e.g. "legacy.") in ini file to '
- 'use instead of commandline db params')
- parser.add_argument('-s', '--source', dest='source', default='mysql',
- help='Database type to extract from (only mysql for now)')
- parser.add_argument('--db_name', dest='db_name', default='mediawiki',
- help='Database name')
- parser.add_argument('--host', dest='host', default='localhost',
- help='Database host')
- parser.add_argument('--port', dest='port', type=int, default=0,
- help='Database port')
- parser.add_argument('--user', dest='user', default='',
- help='User for database connection')
- parser.add_argument('--password', dest='password', default='',
- help='Password for database connection')
- parser.add_argument(
- '--keep-dumps', action='store_true', dest='keep_dumps',
- help='Leave dump files on disk after run')
- return parser
-
- @classmethod
- def execute(cls, options):
- options = cls.handle_options(options)
-
- try:
- if options.extract:
- MySQLExtractor(options).extract()
- if options.load:
- MediawikiLoader(options).load()
- finally:
- if not options.keep_dumps:
- shutil.rmtree(options.dump_dir)
-
- @classmethod
- def handle_options(cls, options):
- if not options.extract and not options.load:
- # if action doesn't specified - do both
- options.extract = True
- options.load = True
-
- if not options.dump_dir:
- if options.load and not options.extract:
- raise ValueError(
- 'You must specify directory containing dump files')
- else:
- options.dump_dir = tempfile.mkdtemp()
- log.info("Writing temp files to %s", options.dump_dir)
-
- if options.load and (not options.project or not options.nbhd):
- raise ValueError('You must specify neighborhood and project '
- 'to load data')
-
- if options.extract:
- if options.db_config_prefix:
- for k, v in h.config_with_prefix(config, options.db_config_prefix).iteritems():
- if k == 'port':
- v = int(v)
- setattr(options, k, v)
-
- if options.source == 'mysql':
- pass
- elif options.source in ('sqlite', 'postgres', 'sql-dump'):
- raise ValueError(
- 'This source not implemented yet. Only mysql for now')
- else:
- raise ValueError('You must specify a valid data source')
-
- if not options.attachments_dir:
- raise ValueError(
- 'You must specify path to directory with mediawiki attachmets dump.')
-
- return options
-
-
-if __name__ == '__main__':
- Wiki2Markdown.main()
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6d00c66d/ForgeWiki/forgewiki/tests/test_wiki2markdown.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/test_wiki2markdown.py b/ForgeWiki/forgewiki/tests/test_wiki2markdown.py
deleted file mode 100644
index f021742..0000000
--- a/ForgeWiki/forgewiki/tests/test_wiki2markdown.py
+++ /dev/null
@@ -1,329 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-import os
-import json
-from datetime import datetime
-
-import mock
-from IPython.testing.decorators import module_not_available, skipif
-from pylons import app_globals as g
-
-from forgewiki.scripts.wiki2markdown.extractors import MySQLExtractor
-from forgewiki.scripts.wiki2markdown.loaders import MediawikiLoader
-from alluratest.controller import setup_basic_test
-from allura import model as M
-from forgewiki import model as WM
-from allura.lib import helpers as h
-
-from pylons import tmpl_context as context
-
-
-class TestMySQLExtractor(object):
-
- def setUp(self):
- setup_basic_test()
- self.options = mock.Mock()
- self.options.dump_dir = os.path.join(g.tmpdir, 'w2m_test')
-
- # monkey-patch MySQLExtractor for test
- def pages(self):
- yield {'page_id': 1, 'title': 'Test title'}
- yield {'page_id': 2, 'title': 'Main_Page'}
- yield {'page_id': 3, 'title': 'Test'}
-
- def history(self, page_id):
- data = {
- 1: [
- {'timestamp': 1, 'text': "Test", 'username': 'test-user'},
- {'timestamp': 2, 'text': "Test Text", 'username': 'bad'}
- ],
- 2: [
- {'timestamp': 1, 'text': "Main_Page", 'username': 'b'},
- {'timestamp': 2, 'text': "Main_Page text", 'username': 'b'}
- ],
- 3: [
- {'timestamp': 1, 'text': "Some test text", 'username': ''},
- {'timestamp': 2, 'text': "", 'username': ''}
- ]
- }
- revisions = data[page_id]
- for rev in revisions:
- yield rev
-
- def talk(self, page_title):
- return {
- 'text': 'Talk for page %s.' % page_title,
- 'timestamp': 1,
- 'username': 'test-user'
- }
-
- def attachments(self, *args, **kwargs):
- # make 'empty' iterator
- if False:
- yield
-
- MySQLExtractor._pages = pages
- MySQLExtractor._history = history
- MySQLExtractor._talk = talk
- MySQLExtractor._attachments = attachments
- self.extractor = MySQLExtractor(self.options)
-
- def test_extract_pages(self):
- """Test that pages and edit history extracted properly"""
- self.extractor.extract_pages()
-
- # rev 1 of page 1
- with open(os.path.join(self.options.dump_dir, 'pages/1/history/1.json'), 'r') as f:
- page = json.load(f)
- res_page = {
- 'timestamp': 1,
- 'text': 'Test',
- 'page_id': 1,
- 'title': 'Test title',
- 'username': 'test-user'
- }
- assert page == res_page
-
- # rev 2 of page 1
- with open(os.path.join(self.options.dump_dir, 'pages/1/history/2.json'), 'r') as f:
- page = json.load(f)
- res_page = {
- 'timestamp': 2,
- 'text': 'Test Text',
- 'page_id': 1,
- 'title': 'Test title',
- 'username': 'bad'
- }
- assert page == res_page
-
- # rev 1 of page 2
- with open(os.path.join(self.options.dump_dir, 'pages/2/history/1.json'), 'r') as f:
- page = json.load(f)
- res_page = {
- 'timestamp': 1,
- 'text': 'Main_Page',
- 'page_id': 2,
- 'title': 'Main_Page',
- 'username': 'b'
- }
- assert page == res_page
-
- # rev 2 of page 2
- with open(os.path.join(self.options.dump_dir, 'pages/2/history/2.json'), 'r') as f:
- page = json.load(f)
- res_page = {
- 'timestamp': 2,
- 'text': 'Main_Page text',
- 'page_id': 2,
- 'title': 'Main_Page',
- 'username': 'b'
- }
- assert page == res_page
-
- # rev 1 of page 3
- with open(os.path.join(self.options.dump_dir, 'pages/3/history/1.json'), 'r') as f:
- page = json.load(f)
- res_page = {
- 'timestamp': 1,
- 'text': 'Some test text',
- 'page_id': 3,
- 'title': 'Test',
- 'username': ''
- }
- assert page == res_page
-
- # rev 2 of page 3
- with open(os.path.join(self.options.dump_dir, 'pages/3/history/2.json'), 'r') as f:
- page = json.load(f)
- res_page = {
- 'timestamp': 2,
- 'text': '',
- 'page_id': 3,
- 'title': 'Test',
- 'username': ''
- }
- assert page == res_page
-
- def test_extract_talk(self):
- """Test that talk pages extracted properly."""
- pages = [
- {'page_id': 1, 'title': 'Test 1'},
- {'page_id': 2, 'title': 'Test 2'},
- {'page_id': 3, 'title': 'Test 3'},
- ]
- for page in pages:
- self.extractor.extract_talk(page)
-
- with open(os.path.join(self.options.dump_dir, 'pages/1/discussion.json'), 'r') as f:
- page = json.load(f)
- assert page == {
- 'text': 'Talk for page Test 1.',
- 'username': 'test-user',
- 'timestamp': 1}
-
- with open(os.path.join(self.options.dump_dir, 'pages/2/discussion.json'), 'r') as f:
- page = json.load(f)
- assert page == {
- 'text': 'Talk for page Test 2.',
- 'timestamp': 1,
- 'username': 'test-user'}
-
- with open(os.path.join(self.options.dump_dir, 'pages/3/discussion.json'), 'r') as f:
- page = json.load(f)
- assert page == {
- 'text': 'Talk for page Test 3.',
- 'timestamp': 1,
- 'username': 'test-user'}
-
-
-class TestMediawikiLoader(object):
-
- def setUp(self):
- setup_basic_test()
- self.options = mock.Mock()
- # need test project with installed wiki app
- self.options.nbhd = 'Adobe'
- self.options.project = '--init--'
-
- nbhd = M.Neighborhood.query.get(name=self.options.nbhd)
- h.set_context(self.options.project, 'wiki', neighborhood=nbhd)
-
- # monkey-patch MediawikiLoader for test
- def pages(self):
- yield 1
- yield 2
-
- def history(self, page_dir):
- data = {
- 1: [
- {
- 'title': 'Test title',
- 'text': "'''bold''' ''italics''",
- 'page_id': 1,
- 'timestamp': '20120808000001',
- 'username': 'test-user'
- },
- {
- 'title': 'Test title',
- 'text': "'''bold'''",
- 'page_id': 1,
- 'timestamp': '20120809000001',
- 'username': 'test-user'
- },
- ],
- 2: [
- {
- 'title': 'Main',
- 'text': "Main text rev 1",
- 'page_id': 2,
- 'timestamp': '20120808000001',
- 'username': 'bad-user'
- },
- {
- 'title': 'Main',
- 'text': "Main text rev 2",
- 'page_id': 2,
- 'timestamp': '20120809000001',
- 'username': 'bad-user'
- },
-
- ],
- }
- for page in data[page_dir]:
- yield page
-
- def talk(self, page_dir):
- data = {
- 1: {
- 'text': "''Talk page'' for page 1.",
- 'username': 'test-user',
- 'timestamp': '20120809000001'
- },
- 2: {
- 'text': "''Talk page'' for page 2.",
- 'username': 'bad-user',
- 'timestamp': '20120809000001'
- },
- }
- return data[page_dir]
-
- def attachments(self, *args, **kwargs):
- # make 'empty' iterator
- if False:
- yield
-
- MediawikiLoader._pages = pages
- MediawikiLoader._history = history
- MediawikiLoader._talk = talk
- MediawikiLoader._attachments = attachments
- self.loader = MediawikiLoader(self.options)
-
- def get_page(self, title):
- return WM.Page.query.get(app_config_id=context.app.config._id,
- title=title)
-
- def get_post(self, title):
- page = self.get_page(title)
- thread = M.Thread.query.get(ref_id=page.index_id())
- return M.Post.query.get(discussion_id=thread.discussion_id,
- thread_id=thread._id)
-
- @skipif(module_not_available('mediawiki'))
- @mock.patch('allura.model.discuss.g.director')
- def test_load_pages(self, director):
- """Test that pages, edit history and talk loaded properly"""
- self.loader.load_pages()
- page = self.get_page('Test title')
-
- assert page.mod_date == datetime.strptime('20120809000001',
- self.loader.TIMESTAMP_FMT)
- assert page.authors()[0].username == 'test-user'
- assert '**bold**' in page.text
- # _italics should be only in the first revision of page
- assert '_italics_' not in page
-
- page = page.get_version(1)
- assert '**bold** _italics_' in page.text
- assert page.mod_date == datetime.strptime('20120808000001',
- self.loader.TIMESTAMP_FMT)
- assert page.authors()[0].username == 'test-user'
-
- page = self.get_page('Main')
- assert page.mod_date == datetime.strptime('20120809000001',
- self.loader.TIMESTAMP_FMT)
- assert page.authors()[0].username == '*anonymous'
- assert 'Main text rev 2' in page.text
-
- page = page.get_version(1)
- assert page.mod_date == datetime.strptime('20120808000001',
- self.loader.TIMESTAMP_FMT)
- assert page.authors()[0].username == '*anonymous'
- assert 'Main text rev 1' in page.text
-
- # Check that talk pages loaded
- post = self.get_post('Test title')
- assert post.timestamp == datetime.strptime('20120809000001',
- self.loader.TIMESTAMP_FMT)
- assert post.author().username == 'test-user'
- assert '_Talk page_ for page 1.' in post.text
-
- post = self.get_post('Main')
- assert post.timestamp == datetime.strptime('20120809000001',
- self.loader.TIMESTAMP_FMT)
- assert post.author().username == '*anonymous'
- assert '_Talk page_ for page 2.' in post.text
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6d00c66d/ForgeWiki/setup.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/setup.py b/ForgeWiki/setup.py
index 041eadc..76db941 100644
--- a/ForgeWiki/setup.py
+++ b/ForgeWiki/setup.py
@@ -42,8 +42,5 @@ setup(name='ForgeWiki',
# -*- Entry points: -*-
[allura]
Wiki=forgewiki.wiki_main:ForgeWikiApp
-
- [paste.paster_command]
- wiki2markdown = forgewiki.command.wiki2markdown:Wiki2MarkDownCommand
""",
)
[3/3] git commit: [#6484] Update / add requirements for TracWiki and
MediaWiki importers
Posted by jo...@apache.org.
[#6484] Update / add requirements for TracWiki and MediaWiki importers
Signed-off-by: Cory Johns <cj...@slashdotmedia.com>
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/491fbbf1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/491fbbf1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/491fbbf1
Branch: refs/heads/master
Commit: 491fbbf18fdff87b2e5233e35d41eeea71f5c3c8
Parents: 0e987b8
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Jan 13 17:41:59 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Mon Jan 13 17:43:14 2014 +0000
----------------------------------------------------------------------
Allura/test.ini | 8 ++++++++
requirements-sf.txt | 3 ++-
2 files changed, 10 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/491fbbf1/Allura/test.ini
----------------------------------------------------------------------
diff --git a/Allura/test.ini b/Allura/test.ini
index 5ae2aef..2d71468 100644
--- a/Allura/test.ini
+++ b/Allura/test.ini
@@ -40,6 +40,14 @@ db_prefix = test_
site_name = Allura
base_url = http://localhost
+mediawikiimporter.db_config_prefix = hostedapps.db.
+mediawikiimporter.attachments_dir_prefix = /nfs/mediawiki-attachments/
+mediawikiimporter.db_name_template = p_%s_mediawiki
+hostedapps.db.host = localhost
+hostedapps.db.port = 3306
+hostedapps.db.user = user
+hostedapps.db.password = password
+
# Use test MongoDB DB server
# ming.main.master = mongo://127.0.0.1:27018/allura
ming.main.uri = mim:///allura
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/491fbbf1/requirements-sf.txt
----------------------------------------------------------------------
diff --git a/requirements-sf.txt b/requirements-sf.txt
index 73b97ab..e2900fe 100644
--- a/requirements-sf.txt
+++ b/requirements-sf.txt
@@ -20,7 +20,8 @@ wsgipreload==1.2
pyzmq==2.1.7
html2text==3.200.3dev-20121112
PyMollom==0.1
-TracWikiImporter==0.3.4
+TracWikiImporter==0.3.5
+MediaWikiImporter=0.0.1
Unidecode==0.04.14
# use version built from https://github.com/johnsca/GitPython/commits/tv/6000
[2/3] git commit: [#6484] ticket:492 Move wiki_from_trac script to
tracwikiimporter
Posted by jo...@apache.org.
[#6484] ticket:492 Move wiki_from_trac script to tracwikiimporter
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/0e987b83
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/0e987b83
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/0e987b83
Branch: refs/heads/master
Commit: 0e987b836da97d98b57dfccbda51f69a5c5ed337
Parents: 6d00c66
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Jan 2 10:44:27 2014 +0200
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Mon Jan 13 17:43:14 2014 +0000
----------------------------------------------------------------------
ForgeWiki/forgewiki/scripts/__init__.py | 16 --
.../scripts/wiki_from_trac/__init__.py | 18 --
.../scripts/wiki_from_trac/extractors.py | 244 -------------------
.../forgewiki/scripts/wiki_from_trac/loaders.py | 73 ------
.../scripts/wiki_from_trac/wiki_from_trac.py | 81 ------
scripts/allura_import.py | 2 +-
scripts/wiki-export.py | 2 +-
7 files changed, 2 insertions(+), 434 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0e987b83/ForgeWiki/forgewiki/scripts/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/scripts/__init__.py b/ForgeWiki/forgewiki/scripts/__init__.py
deleted file mode 100644
index 144e298..0000000
--- a/ForgeWiki/forgewiki/scripts/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0e987b83/ForgeWiki/forgewiki/scripts/wiki_from_trac/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/scripts/wiki_from_trac/__init__.py b/ForgeWiki/forgewiki/scripts/wiki_from_trac/__init__.py
deleted file mode 100644
index 625362c..0000000
--- a/ForgeWiki/forgewiki/scripts/wiki_from_trac/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-from .wiki_from_trac import WikiFromTrac
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0e987b83/ForgeWiki/forgewiki/scripts/wiki_from_trac/extractors.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/scripts/wiki_from_trac/extractors.py b/ForgeWiki/forgewiki/scripts/wiki_from_trac/extractors.py
deleted file mode 100644
index 7f146e6..0000000
--- a/ForgeWiki/forgewiki/scripts/wiki_from_trac/extractors.py
+++ /dev/null
@@ -1,244 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-import logging
-import re
-import sys
-import json
-import traceback
-from urllib import quote, unquote
-from urlparse import urljoin, urlsplit
-
-try:
- from forgeimporters.base import ProjectExtractor
- urlopen = ProjectExtractor.urlopen
-except ImportError:
- try:
- from allura.lib.helpers import urlopen
- except ImportError:
- from urllib2 import urlopen
-
-try:
- # Ignore this import if the html2text package is not installed
- import html2text
-except ImportError:
- pass
-
-from BeautifulSoup import BeautifulSoup
-
-log = logging.getLogger(__name__)
-
-
-class WikiExporter(object):
-
- PAGE_LIST_URL = 'wiki/TitleIndex'
- PAGE_URL = 'wiki/%s'
- CONTENT_DIV_ATTRS = {'class': 'wikipage searchable'}
- EXCLUDE_PAGES = [
- 'CamelCase',
- 'InterMapTxt',
- 'InterTrac',
- 'InterWiki',
- 'PageTemplates',
- 'SandBox',
- 'TitleIndex',
- 'TracAccessibility',
- 'TracAdmin',
- 'TracBackup',
- 'TracBrowser',
- 'TracChangeset',
- 'TracEnvironment',
- 'TracFineGrainedPermissions',
- 'TracGuide',
- 'TracImport',
- 'TracIni',
- 'TracInterfaceCustomization',
- 'TracLinks',
- 'TracLogging',
- 'TracNavigation',
- 'TracNotification',
- 'TracPermissions',
- 'TracPlugins',
- 'TracQuery',
- 'TracReports',
- 'TracRevisionLog',
- 'TracRoadmap',
- 'TracRss',
- 'TracSearch',
- 'TracSupport',
- 'TracSyntaxColoring',
- 'TracTickets',
- 'TracTicketsCustomFields',
- 'TracTimeline',
- 'TracUnicode',
- 'TracWiki',
- 'TracWorkflow',
- 'WikiDeletePage',
- 'WikiFormatting',
- 'WikiHtml',
- 'WikiMacros',
- 'WikiNewPage',
- 'WikiPageNames',
- 'WikiProcessors',
- 'WikiRestructuredText',
- 'WikiRestructuredTextLinks',
- 'RecentChanges',
- ]
- RENAME_PAGES = {
- 'WikiStart': 'Home', # Change the start page name to Home
- 'Home': 'WikiStart', # Rename the Home page to WikiStart
- }
-
- def __init__(self, base_url, options):
- self.base_url = base_url
- self.options = options
-
- def export(self, out):
- pages = []
- for title in self.page_list():
- try:
- pages.append(self.get_page(title))
- except:
- self.log('Cannot fetch page %s. Skipping' % title)
- self.log(traceback.format_exc())
- continue
- out.write(json.dumps(pages, indent=2, sort_keys=True))
- out.write('\n')
-
- def log(self, msg):
- log.info(msg)
- if self.options.verbose:
- print >>sys.stderr, msg
-
- def url(self, suburl, type=None):
- url = urljoin(self.base_url, suburl)
- if type is None:
- return url
- glue = '&' if '?' in suburl else '?'
- return url + glue + 'format=' + type
-
- def fetch(self, url):
- return urlopen(url)
-
- def page_list(self):
- url = urljoin(self.base_url, self.PAGE_LIST_URL)
- self.log('Fetching list of pages from %s' % url)
- r = self.fetch(url)
- html = BeautifulSoup(r)
- pages = html.find('div', attrs=self.CONTENT_DIV_ATTRS) \
- .find('ul').findAll('li')
- pages = [page.find('a').text
- for page in pages
- if page.find('a')
- and page.find('a').text not in self.EXCLUDE_PAGES]
- # Remove duplicate entries by converting page list to a set.
- # As we're going to fetch all listed pages,
- # it's safe to destroy the original order of pages.
- return set(pages)
-
- def get_page(self, title):
- title = quote(title)
- convert_method = '_get_page_' + self.options.converter
- content = getattr(self, convert_method)(title)
- page = {
- 'title': self.convert_title(title),
- 'text': self.convert_content(content),
- 'labels': '',
- }
- return page
-
- def _get_page_html2text(self, title):
- url = self.url(self.PAGE_URL % title)
- self.log('Fetching page %s' % url)
- r = self.fetch(url)
- html = BeautifulSoup(r)
- return html.find('div', attrs=self.CONTENT_DIV_ATTRS)
-
- def _get_page_regex(self, title):
- url = self.url(self.PAGE_URL % title, 'txt')
- self.log('Fetching page %s' % url)
- r = self.fetch(url)
- return r
-
- def convert_title(self, title):
- title = self.RENAME_PAGES.get(title, title)
- title = title.replace('/', '-') # Handle subpages
- title = title.rstrip('?') # Links to non-existent pages ends with '?'
- return title
-
- def convert_content(self, content):
- convert_method = '_convert_content_' + self.options.converter
- return getattr(self, convert_method)(content)
-
- def _convert_wiki_toc_to_markdown(self, content):
- """
- Removes contents of div.wiki-toc elements and replaces them with
- the '[TOC]' markdown macro.
- """
- for toc in content('div', attrs={'class': 'wiki-toc'}):
- toc.string = '[TOC]'
- return content
-
- def _convert_content_html2text(self, content):
- html2text.BODY_WIDTH = 0 # Don't wrap lines
- content = self._convert_wiki_toc_to_markdown(content)
- content = html2text.html2text(unicode(content))
- # Convert internal links
- internal_url = urlsplit(self.base_url).path + 'wiki/'
- internal_link_re = r'\[([^]]+)\]\(%s([^)]*)\)' % internal_url
- internal_link = re.compile(internal_link_re, re.UNICODE)
-
- def sub(match):
- caption = match.group(1)
- page = self.convert_title(match.group(2))
- if caption == page:
- link = '[%s]' % unquote(page)
- else:
- link = '[%s](%s)' % (caption, page)
- return link
- return internal_link.sub(sub, content)
-
- def _convert_content_regex(self, text):
- # https://gist.github.com/sgk/1286682
- text = re.sub('\r\n', '\n', text)
- text = re.sub(r'{{{(.*?)}}}', r'`\1`', text)
-
- def indent4(m):
- return '\n ' + m.group(1).replace('\n', '\n ')
-
- text = re.sub(r'(?sm){{{\n(.*?)\n}}}', indent4, text)
- text = re.sub(r'(?m)^====\s+(.*?)\s+====$', r'#### \1', text)
- text = re.sub(r'(?m)^===\s+(.*?)\s+===$', r'### \1', text)
- text = re.sub(r'(?m)^==\s+(.*?)\s+==$', r'## \1', text)
- text = re.sub(r'(?m)^=\s+(.*?)\s+=$', r'# \1', text)
- text = re.sub(r'^ * ', r'****', text)
- text = re.sub(r'^ * ', r'***', text)
- text = re.sub(r'^ * ', r'**', text)
- text = re.sub(r'^ * ', r'*', text)
- text = re.sub(r'^ \d+. ', r'1.', text)
- a = []
- for line in text.split('\n'):
- if not line.startswith(' '):
- line = re.sub(
- r'\[(https?://[^\s\[\]]+)\s([^\[\]]+)\]', r'[\2](\1)', line)
- line = re.sub(r'\[(wiki:[^\s\[\]]+)\s([^\[\]]+)\]',
- r'[\2](/\1/)', line)
- line = re.sub(r'\!(([A-Z][a-z0-9]+){2,})', r'\1', line)
- line = re.sub(r'\'\'\'(.*?)\'\'\'', r'*\1*', line)
- line = re.sub(r'\'\'(.*?)\'\'', r'_\1_', line)
- a.append(line)
- return '\n'.join(a)
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0e987b83/ForgeWiki/forgewiki/scripts/wiki_from_trac/loaders.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/scripts/wiki_from_trac/loaders.py b/ForgeWiki/forgewiki/scripts/wiki_from_trac/loaders.py
deleted file mode 100644
index 58701a3..0000000
--- a/ForgeWiki/forgewiki/scripts/wiki_from_trac/loaders.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-import json
-
-from allura.lib.import_api import AlluraImportApiClient
-
-
-def load_data(doc_file_name=None, optparser=None, options=None):
- import_options = {}
- for s in options.import_opts:
- k, v = s.split('=', 1)
- if v == 'false':
- v = False
- import_options[k] = v
-
- user_map = {}
- if options.user_map_file:
- f = open(options.user_map_file)
- try:
- user_map = json.load(f)
- if type(user_map) is not type({}):
- raise ValueError
- for k, v in user_map.iteritems():
- print k, v
- if not isinstance(k, basestring) or not isinstance(v, basestring):
- raise ValueError
- except ValueError:
- optparser.error(
- '--user-map should specify JSON file with format {"original_user": "sf_user", ...}')
- finally:
- f.close()
-
- import_options['user_map'] = user_map
-
- cli = AlluraImportApiClient(
- options.base_url, options.api_key, options.secret_key, options.verbose)
- doc_txt = open(doc_file_name).read()
-
- if options.wiki:
- import_wiki(cli, options.project, options.wiki, options, doc_txt)
-
-
-def import_wiki(cli, project, tool, options, doc_txt):
- url = '/rest/p/' + project + '/' + tool
- doc = json.loads(doc_txt)
- if 'wiki' in doc and 'default' in doc['wiki'] and 'artifacts' in doc['wiki']['default']:
- pages = doc['trackers']['default']['artifacts']
- else:
- pages = doc
- if options.verbose:
- print "Processing %d pages" % len(pages)
- for page in pages:
- title = page.pop('title').encode('utf-8')
- page['text'] = page['text'].encode('utf-8')
- page['labels'] = page['labels'].encode('utf-8')
- r = cli.call(url + '/' + title, **page)
- assert r == {}
- print 'Imported wiki page %s' % title
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0e987b83/ForgeWiki/forgewiki/scripts/wiki_from_trac/wiki_from_trac.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/scripts/wiki_from_trac/wiki_from_trac.py b/ForgeWiki/forgewiki/scripts/wiki_from_trac/wiki_from_trac.py
deleted file mode 100644
index 0897f00..0000000
--- a/ForgeWiki/forgewiki/scripts/wiki_from_trac/wiki_from_trac.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-import argparse
-import logging
-from tempfile import NamedTemporaryFile
-
-from forgewiki.scripts.wiki_from_trac.extractors import WikiExporter
-from forgewiki.scripts.wiki_from_trac.loaders import load_data
-
-from allura.scripts import ScriptTask
-
-
-log = logging.getLogger(__name__)
-
-
-class WikiFromTrac(ScriptTask):
-
- """Import Trac Wiki to Allura Wiki"""
- @classmethod
- def parser(cls):
- parser = argparse.ArgumentParser(description='Import wiki from'
- 'Trac to allura wiki')
-
- parser.add_argument('trac_url', type=str, help='Trac URL')
- parser.add_argument('-a', '--api-ticket',
- dest='api_key', help='API ticket')
- parser.add_argument('-s', '--secret-key',
- dest='secret_key', help='Secret key')
- parser.add_argument('-p', '--project', dest='project',
- help='Project to import to')
- parser.add_argument('-t', '--tracker', dest='tracker',
- help='Tracker to import to')
- parser.add_argument('-f', '--forum', dest='forum',
- help='Forum tool to import to')
- parser.add_argument('-w', '--wiki', dest='wiki',
- help='Wiki tool to import to')
- parser.add_argument('-u', '--base-url', dest='base_url',
- default='https://sourceforge.net', help='Base Allura (%(default)s for default)')
- parser.add_argument('-o', dest='import_opts',
- default=[], action='append', help='Specify import option(s)', metavar='opt=val')
- parser.add_argument('--user-map', dest='user_map_file',
- help='Map original users to SF.net users', metavar='JSON_FILE')
- parser.add_argument('--validate', dest='validate',
- action='store_true', help='Validate import data')
- parser.add_argument('-v', '--verbose', dest='verbose',
- action='store_true', help='Verbose operation')
- parser.add_argument('-c', '--continue', dest='cont',
- action='store_true', help='Continue import into existing tracker')
- parser.add_argument('-C', '--converter', dest='converter',
- default='html2text',
- help='Converter to use on wiki text. '
- 'Available options: '
- 'html2text (default) or regex')
-
- return parser
-
- @classmethod
- def execute(cls, options):
- with NamedTemporaryFile() as f:
- WikiExporter(options.trac_url, options).export(f)
- f.flush()
- load_data(f.name, cls.parser(), options)
-
-
-if __name__ == '__main__':
- WikiFromTrac.main()
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0e987b83/scripts/allura_import.py
----------------------------------------------------------------------
diff --git a/scripts/allura_import.py b/scripts/allura_import.py
index 0f2f715..56bc5d5 100644
--- a/scripts/allura_import.py
+++ b/scripts/allura_import.py
@@ -20,7 +20,7 @@ from optparse import OptionParser
from allura.lib.import_api import AlluraImportApiClient
from forgetracker.scripts.import_tracker import import_tracker
-from forgewiki.scripts.wiki_from_trac.loaders import import_wiki
+from tracwikiimporter.scripts.wiki_from_trac.loaders import import_wiki
def main():
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0e987b83/scripts/wiki-export.py
----------------------------------------------------------------------
diff --git a/scripts/wiki-export.py b/scripts/wiki-export.py
index e64458e..025d3ca 100755
--- a/scripts/wiki-export.py
+++ b/scripts/wiki-export.py
@@ -20,7 +20,7 @@
import sys
from optparse import OptionParser
-from forgewiki.scripts.wiki_from_trac.extractors import WikiExporter
+from tracwikiimporter.scripts.wiki_from_trac.extractors import WikiExporter
def parse_options():