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 |
|
27 | import StringIO
|
28 | import fileinput
|
29 | import plistlib
|
30 | import os
|
31 | import re
|
32 | import sys
|
33 | from xml.dom import minidom
|
34 | from xml.etree import ElementTree
|
35 |
|
36 |
|
37 | def Usage():
|
38 | sys.stderr.write(__doc__)
|
39 | sys.exit(1)
|
40 |
|
41 |
|
42 | def ValueToElement(node_name, key, value):
|
43 | if isinstance(value, bool):
|
44 | value = str(value).lower()
|
45 | return ElementTree.Element(node_name, attrib={'name':key, 'value':str(value)})
|
46 |
|
47 |
|
48 | def AppendDict(d, node, name, ignore=()):
|
49 | for key in sorted(d):
|
50 | if key not in ignore:
|
51 | node.append(ValueToElement(name, key, d[key]))
|
52 |
|
53 |
|
54 | def FindProjectFile(path):
|
55 | # Do an extra abspath here to strip off trailing / if present.
|
56 | path = os.path.abspath(path)
|
57 | if path.endswith('.pbxproj'):
|
58 | return path
|
59 | elif path.endswith('.xcodeproj'):
|
60 | return os.path.join(path, 'project.pbxproj')
|
61 | for f in os.listdir(path):
|
62 | if f.endswith('.xcodeproj'):
|
63 | return os.path.join(path, f, 'project.pbxproj')
|
64 | raise Exception('Invalid project path. Please provide the path to your .xcodeproj directory')
|
65 |
|
66 |
|
67 | def FindPlistFile(search_path):
|
68 | for root, unused_dirnames, file_names in os.walk(search_path):
|
69 | for file_name in file_names:
|
70 | if file_name == 'Cordova.plist':
|
71 | return os.path.join(root, file_name)
|
72 | raise Exception('Could not find a file named "Cordova.plist" within ' + search_path)
|
73 |
|
74 |
|
75 | def ConvertPlist(src_path, dst_path):
|
76 | # Run it through plutil to ensure it's not a binary plist.
|
77 | os.system("plutil -convert xml1 '%s'" % src_path)
|
78 | plist = plistlib.readPlist(src_path)
|
79 | root = ElementTree.Element('cordova')
|
80 |
|
81 | AppendDict(plist, root, 'preference', ignore=('Plugins', 'ExternalHosts'))
|
82 |
|
83 | plugins = ElementTree.Element('plugins')
|
84 | root.append(plugins)
|
85 | AppendDict(plist['Plugins'], plugins, 'plugin')
|
86 |
|
87 | for value in sorted(plist['ExternalHosts']):
|
88 | root.append(ElementTree.Element('access', attrib={'origin':value}))
|
89 |
|
90 | tree = ElementTree.ElementTree(root)
|
91 | s = StringIO.StringIO()
|
92 | tree.write(s, encoding='UTF-8')
|
93 | mini_dom = minidom.parseString(s.getvalue())
|
94 | with open(dst_path, 'w') as out:
|
95 | out.write(mini_dom.toprettyxml(encoding='UTF-8'))
|
96 |
|
97 |
|
98 | def UpdateProjectFile(path):
|
99 | file_handle = fileinput.input(path, inplace=1)
|
100 | for line in file_handle:
|
101 | if 'Cordova.plist' in line:
|
102 | line = line.replace('Cordova.plist', 'config.xml')
|
103 | line = line.replace('lastKnownFileType = text.plist.xml', 'lastKnownFileType = text.xml')
|
104 | print line,
|
105 | file_handle.close()
|
106 |
|
107 |
|
108 | def main(argv):
|
109 | if len(argv) != 1:
|
110 | Usage();
|
111 |
|
112 | project_file = FindProjectFile(argv[0])
|
113 | plist_file = FindPlistFile(os.path.dirname(os.path.dirname(project_file)))
|
114 |
|
115 | config_file = os.path.join(os.path.dirname(plist_file), 'config.xml')
|
116 | sys.stdout.write('Converting %s to %s.\n' % (plist_file, config_file))
|
117 | ConvertPlist(plist_file, config_file)
|
118 |
|
119 | sys.stdout.write('Updating references in %s\n' % project_file)
|
120 | UpdateProjectFile(project_file)
|
121 |
|
122 | os.unlink(plist_file)
|
123 | sys.stdout.write('Updates Complete.\n')
|
124 |
|
125 |
|
126 | if __name__ == '__main__':
|
127 | main(sys.argv[1:])
|