Skip to content

Commit 01998d8

Browse files
authored
Merge pull request #9 from stasm/migrate
Rebase the migration tools from python-l20n
2 parents 1a30802 + 7a31836 commit 01998d8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+4771
-70
lines changed

fluent/migrate/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# coding=utf8
2+
3+
from .context import MergeContext # noqa: F401
4+
from .transforms import ( # noqa: F401
5+
CONCAT, EXTERNAL, LITERAL, LITERAL_FROM, PLURALS, PLURALS_FROM, REPLACE,
6+
REPLACE_FROM, SOURCE
7+
)
8+
from .changesets import convert_blame_to_changesets # noqa: F401

fluent/migrate/changesets.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# coding=utf8
2+
3+
import time
4+
5+
6+
def by_first_commit(item):
7+
"""Order two changesets by their first commit date."""
8+
return item['first_commit']
9+
10+
11+
def convert_blame_to_changesets(blame_json):
12+
"""Convert a blame dict into a list of changesets.
13+
14+
The blame information in `blame_json` should be a dict of the following
15+
structure:
16+
17+
{
18+
'authors': [
19+
'A.N. Author <author@example.com>',
20+
],
21+
'blame': {
22+
'path/one': {
23+
'key1': [0, 1346095921.0],
24+
},
25+
}
26+
}
27+
28+
It will be transformed into a list of changesets which can be fed into
29+
`MergeContext.serialize_changeset`:
30+
31+
[
32+
{
33+
'author': 'A.N. Author <author@example.com>',
34+
'first_commit': 1346095921.0,
35+
'changes': {
36+
('path/one', 'key1'),
37+
}
38+
},
39+
]
40+
41+
"""
42+
now = time.time()
43+
changesets = [
44+
{
45+
'author': author,
46+
'first_commit': now,
47+
'changes': set()
48+
} for author in blame_json['authors']
49+
]
50+
51+
for path, keys_info in blame_json['blame'].items():
52+
for key, (author_index, timestamp) in keys_info.items():
53+
changeset = changesets[author_index]
54+
changeset['changes'].add((path, key))
55+
if timestamp < changeset['first_commit']:
56+
changeset['first_commit'] = timestamp
57+
58+
return sorted(changesets, key=by_first_commit)

fluent/migrate/cldr.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# coding=utf8
2+
3+
import pkgutil
4+
import json
5+
6+
7+
def in_canonical_order(item):
8+
return canonical_order.index(item)
9+
10+
11+
cldr_plurals = json.loads(
12+
pkgutil.get_data('fluent.migrate', 'cldr_data/plurals.json').decode('utf-8')
13+
)
14+
15+
rules = cldr_plurals['supplemental']['plurals-type-cardinal']
16+
canonical_order = ('zero', 'one', 'two', 'few', 'many', 'other')
17+
18+
categories = {}
19+
for lang, rules in rules.items():
20+
categories[lang] = tuple(sorted(map(
21+
lambda key: key.replace('pluralRule-count-', ''),
22+
rules.keys()
23+
), key=in_canonical_order))
24+
25+
26+
def get_plural_categories(lang):
27+
"""Return a tuple of CLDR plural categories for `lang`.
28+
29+
If an exact match for `lang` is not available, recursively fall back to
30+
a language code with the last subtag stripped. That is, if `ja-JP-mac` is
31+
not defined in CLDR, the code will try `ja-JP` and then `ja`.
32+
33+
If no matches are found, a `RuntimeError` is raised.
34+
35+
>>> get_plural_categories('sl')
36+
('one', 'two', 'few', 'other')
37+
>>> get_plural_categories('ga-IE')
38+
('one', 'few', 'two', 'few', 'other')
39+
>>> get_plural_categories('ja-JP-mac')
40+
('other')
41+
42+
"""
43+
44+
langs_categories = categories.get(lang, None)
45+
46+
if langs_categories is None:
47+
# Remove the trailing subtag.
48+
fallback_lang, _, _ = lang.rpartition('-')
49+
50+
if fallback_lang == '':
51+
raise RuntimeError('Unknown language: {}'.format(lang))
52+
53+
return get_plural_categories(fallback_lang)
54+
55+
return langs_categories

fluent/migrate/cldr_data/plurals.json

Lines changed: 857 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
2+
3+
Unicode Data Files include all data files under the directories
4+
http://www.unicode.org/Public/, http://www.unicode.org/reports/,
5+
http://www.unicode.org/cldr/data/, http://source.icu-project.org/repos/icu/,
6+
and http://www.unicode.org/utility/trac/browser/.
7+
8+
Unicode Data Files do not include PDF online code charts under the
9+
directory http://www.unicode.org/Public/.
10+
11+
Software includes any source code published in the Unicode Standard
12+
or under the directories
13+
http://www.unicode.org/Public/, http://www.unicode.org/reports/,
14+
http://www.unicode.org/cldr/data/, http://source.icu-project.org/repos/icu/,
15+
and http://www.unicode.org/utility/trac/browser/.
16+
17+
NOTICE TO USER: Carefully read the following legal agreement.
18+
BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA
19+
FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT,
20+
AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT.
21+
IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE
22+
DATA FILES OR SOFTWARE.
23+
24+
COPYRIGHT AND PERMISSION NOTICE
25+
26+
Copyright © 1991-2016 Unicode, Inc. All rights reserved. Distributed under
27+
the Terms of Use in http://www.unicode.org/copyright.html.
28+
29+
Permission is hereby granted, free of charge, to any person obtaining a copy
30+
of the Unicode data files and any associated documentation (the "Data Files")
31+
or Unicode software and any associated documentation (the "Software") to deal
32+
in the Data Files or Software without restriction, including without
33+
limitation the rights to use, copy, modify, merge, publish, distribute,
34+
and/or sell copies of the Data Files or Software, and to permit persons to
35+
whom the Data Files or Software are furnished to do so, provided that either
36+
(a) this copyright and permission notice appear with all copies of the Data
37+
Files or Software, or
38+
(b) this copyright and permission notice appear in associated Documentation.
39+
40+
THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
41+
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
42+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
43+
THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
44+
INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR
45+
CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
46+
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
47+
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
48+
OF THE DATA FILES OR SOFTWARE.
49+
50+
Except as contained in this notice, the name of a copyright holder shall not
51+
be used in advertising or otherwise to promote the sale, use or other
52+
dealings in these Data Files or Software without prior written authorization
53+
of the copyright holder.

0 commit comments

Comments
 (0)