1 | #!/usr/bin/python
|
2 | #
|
3 | # Licensed to the Apache Software Foundation (ASF) under one
|
4 | # or more contributor license agreements. See the NOTICE file
|
5 | # distributed with this work for additional information
|
6 | # regarding copyright ownership. The ASF licenses this file
|
7 | # to you under the Apache License, Version 2.0 (the
|
8 | # "License"); you may not use this file except in compliance
|
9 | # with the License. You may obtain a copy of the License at
|
10 | #
|
11 | # http://www.apache.org/licenses/LICENSE-2.0
|
12 | #
|
13 | # Unless required by applicable law or agreed to in writing,
|
14 | # software distributed under the License is distributed on an
|
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
16 | # KIND, either express or implied. See the License for the
|
17 | # specific language governing permissions and limitations
|
18 | # under the License.
|
19 | #
|
20 | """
|
21 | Converts a project's Cordova.plist file into a config.xml one. This conversion is required for Cordova 2.3.
|
22 |
|
23 | Usage:
|
24 | plist2xml.py path/to/project
|
25 | """
|
26 | from __future__ import print_function
|
27 |
|
28 | import fileinput
|
29 | import io
|
30 | import os
|
31 | import plistlib
|
32 | import re
|
33 | import sys
|
34 | from xml.dom import minidom
|
35 | from xml.etree import ElementTree
|
36 |
|
37 |
|
38 | def Usage():
|
39 | sys.stderr.write(__doc__)
|
40 | sys.exit(1)
|
41 |
|
42 |
|
43 | def ValueToElement(node_name, key, value):
|
44 | if isinstance(value, bool):
|
45 | value = str(value).lower()
|
46 | return ElementTree.Element(node_name, attrib={'name':key, 'value':str(value)})
|
47 |
|
48 |
|
49 | def AppendDict(d, node, name, ignore=()):
|
50 | for key in sorted(d):
|
51 | if key not in ignore:
|
52 | node.append(ValueToElement(name, key, d[key]))
|
53 |
|
54 |
|
55 | def FindProjectFile(path):
|
56 | # Do an extra abspath here to strip off trailing / if present.
|
57 | path = os.path.abspath(path)
|
58 | if path.endswith('.pbxproj'):
|
59 | return path
|
60 | elif path.endswith('.xcodeproj'):
|
61 | return os.path.join(path, 'project.pbxproj')
|
62 | for f in os.listdir(path):
|
63 | if f.endswith('.xcodeproj'):
|
64 | return os.path.join(path, f, 'project.pbxproj')
|
65 | raise Exception('Invalid project path. Please provide the path to your .xcodeproj directory')
|
66 |
|
67 |
|
68 | def FindPlistFile(search_path):
|
69 | for root, unused_dirnames, file_names in os.walk(search_path):
|
70 | for file_name in file_names:
|
71 | if file_name == 'Cordova.plist':
|
72 | return os.path.join(root, file_name)
|
73 | raise Exception('Could not find a file named "Cordova.plist" within ' + search_path)
|
74 |
|
75 |
|
76 | def ConvertPlist(src_path, dst_path):
|
77 | # Run it through plutil to ensure it's not a binary plist.
|
78 | os.system("plutil -convert xml1 '%s'" % src_path)
|
79 | plist = plistlib.readPlist(src_path)
|
80 | root = ElementTree.Element('cordova')
|
81 |
|
82 | AppendDict(plist, root, 'preference', ignore=('Plugins', 'ExternalHosts'))
|
83 |
|
84 | plugins = ElementTree.Element('plugins')
|
85 | root.append(plugins)
|
86 | AppendDict(plist['Plugins'], plugins, 'plugin')
|
87 |
|
88 | for value in sorted(plist['ExternalHosts']):
|
89 | root.append(ElementTree.Element('access', attrib={'origin':value}))
|
90 |
|
91 | tree = ElementTree.ElementTree(root)
|
92 | with io.BytesIO() as s:
|
93 | tree.write(s, encoding='UTF-8')
|
94 | mini_dom = minidom.parseString(s.getvalue())
|
95 | with open(dst_path, 'wb') as out:
|
96 | out.write(mini_dom.toprettyxml(encoding='UTF-8'))
|
97 |
|
98 |
|
99 | def UpdateProjectFile(path):
|
100 | file_handle = fileinput.input(path, inplace=1)
|
101 | for line in file_handle:
|
102 | if 'Cordova.plist' in line:
|
103 | line = line.replace('Cordova.plist', 'config.xml')
|
104 | line = line.replace('lastKnownFileType = text.plist.xml', 'lastKnownFileType = text.xml')
|
105 | print(line, end=' ')
|
106 | file_handle.close()
|
107 |
|
108 |
|
109 | def main(argv):
|
110 | if len(argv) != 1:
|
111 | Usage();
|
112 |
|
113 | project_file = FindProjectFile(argv[0])
|
114 | plist_file = FindPlistFile(os.path.dirname(os.path.dirname(project_file)))
|
115 |
|
116 | config_file = os.path.join(os.path.dirname(plist_file), 'config.xml')
|
117 | sys.stdout.write('Converting %s to %s.\n' % (plist_file, config_file))
|
118 | ConvertPlist(plist_file, config_file)
|
119 |
|
120 | sys.stdout.write('Updating references in %s\n' % project_file)
|
121 | UpdateProjectFile(project_file)
|
122 |
|
123 | os.unlink(plist_file)
|
124 | sys.stdout.write('Updates Complete.\n')
|
125 |
|
126 |
|
127 | if __name__ == '__main__':
|
128 | main(sys.argv[1:])
|