889b5165f59d82ef556d2e2e36b281a3fd755f8e
[platform/framework/web/crosswalk.git] / src / xwalk / app / tools / android / manifest_json_parser.py
1 #!/usr/bin/env python
2
3 # Copyright (c) 2013, 2014 Intel Corporation. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 """
8 Parse JSON-format manifest configuration file and
9 provide the specific fields, which have to be integrated with
10 packaging tool(e.g. make_apk.py) to generate xml-format manifest file.
11
12 Sample usage from shell script:
13 python manifest_json_parser.py --jsonfile=/path/to/manifest.json
14 """
15
16 import json
17 import optparse
18 import os
19 import re
20 import sys
21
22
23 def HandlePermissionList(permission_list):
24   """This function is used to handle the permission list and return the string
25   of permissions.
26
27   Args:
28     permission_list: the permission list, e.g.["permission1", "permission2"].
29
30   Returns:
31     The string of permissions with ':' as separator.
32     e.g. "permission1:permission2".
33   """
34   permissions = list(permission_list)
35   reg_permission = re.compile(r'^[a-zA-Z\.]*$')
36   for permission in permissions:
37     if not reg_permission.match(permission):
38       print('\'Permissions\' field error, only alphabets and '
39             '\'.\' are allowed.')
40       sys.exit(1)
41   return ':'.join(permissions)
42
43
44 def ParseLaunchScreen(ret_dict, launch_screen_dict, orientation):
45   if orientation in launch_screen_dict:
46     sub_dict = launch_screen_dict[orientation]
47     if 'background_color' in sub_dict:
48       ret_dict['launch_screen_background_color_' + orientation] = (
49           sub_dict['background_color'])
50     if 'background_image' in sub_dict:
51       ret_dict['launch_screen_background_image_' + orientation] = (
52           sub_dict['background_image'])
53     if 'image' in sub_dict:
54       ret_dict['launch_screen_image_' + orientation] = (
55           sub_dict['image'])
56     if 'image_border' in sub_dict:
57       ret_dict['launch_screen_image_border_' + orientation] = (
58           sub_dict['image_border'])
59
60
61 def PrintDeprecationWarning(item):
62   print ('WARNING: %s is deprecated for Crosswalk. Please follow '
63          'https://www.crosswalk-project.org/#documentation/manifest.' % item)
64
65
66 class ManifestJsonParser(object):
67   """ The class is used to parse json-format manifest file, recompose the
68   fields and provide the field interfaces required by the packaging tool.
69
70   Args:
71     input_path: the full path of the json-format manifest file.
72   """
73   def __init__(self, input_path):
74     self.input_path = input_path
75     input_file = open(self.input_path)
76     try:
77       input_src = input_file.read()
78       self.data_src = json.JSONDecoder().decode(input_src)
79       self.ret_dict = self._output_items()
80     except (TypeError, ValueError, IOError) as error:
81       print('There is a parser error in manifest.json file: %s' % error)
82       sys.exit(1)
83     except KeyError as error:
84       print('There is a field error in manifest.json file: %s' % error)
85       sys.exit(1)
86     finally:
87       input_file.close()
88
89   def _output_items(self):
90     """ The manifest field items are reorganized and returned as a
91     dictionary to support single or multiple values of keys.
92
93     Returns:
94       A dictionary to the corresponding items. the dictionary keys are
95       described as follows, the value is set to "" if the value of the
96       key is not set.
97     app_name:         The application name.
98     version:          The version number.
99     icons:            An array of icons.
100     app_url:          The url of application, e.g. hosted app.
101     description:      The description of application.
102     app_root:         The root path of the web, this flag allows to package
103                       local web application as apk.
104     app_local_path:   The relative path of entry file based on app_root,
105                       this flag should work with "--app-root" together.
106     permissions:      The permission list.
107     orientation       The default allowed orientations.
108     fullscreen:       The fullscreen flag of the application.
109     launch_screen:    The launch screen configuration.
110     """
111     ret_dict = {}
112     if 'name' not in self.data_src:
113       print('Error: no \'name\' field in manifest.json file.')
114       sys.exit(1)
115     ret_dict['app_name'] = self.data_src['name']
116     ret_dict['version'] = ''
117     if 'version' in self.data_src and 'xwalk_version' in self.data_src:
118       print('WARNING: the value in "version" will be ignored and support '
119             'for it will be removed in the future.')
120       ret_dict['version'] = self.data_src['xwalk_version']
121     elif 'xwalk_version' in self.data_src:
122       ret_dict['version'] = self.data_src['xwalk_version']
123     elif 'version' in self.data_src:
124       PrintDeprecationWarning('version')
125       ret_dict['version'] = self.data_src['version']
126     if 'start_url' in self.data_src:
127       app_url = self.data_src['start_url']
128     elif 'launch_path' in self.data_src:
129       PrintDeprecationWarning('launch_path')
130       app_url = self.data_src['launch_path']
131     elif ('app' in self.data_src and
132           'launch' in self.data_src['app'] and
133           'local_path' in self.data_src['app']['launch']):
134       PrintDeprecationWarning('app.launch.local_path')
135       app_url = self.data_src['app']['launch']['local_path']
136     else:
137       app_url = ''
138     if app_url.lower().startswith(('http://', 'https://')):
139       app_local_path = ''
140     else:
141       app_local_path = app_url
142       app_url = ''
143     file_path_prefix = os.path.split(self.input_path)[0]
144     if 'icons' in self.data_src:
145       icons = self.data_src['icons']
146       if type(icons) == dict:
147         PrintDeprecationWarning('icons defined as dictionary form')
148         ret_dict['icons'] = icons
149       elif type(icons) == list:
150         icons_dict = {}
151         for icon in icons:
152           if 'sizes' in icon and 'src' in icon:
153             icons_dict[icon['sizes'].split('x')[0]] = icon['src']
154         ret_dict['icons'] = icons_dict
155       else:
156         ret_dict['icons'] = {}
157     else:
158       ret_dict['icons'] = {}
159     app_root = file_path_prefix
160     ret_dict['description'] = ''
161     if 'description' in self.data_src and 'xwalk_description' in self.data_src:
162       print('WARNING: the value in "description" will be ignored and support '
163             'for it will be removed in the future.')
164       ret_dict['description'] = self.data_src['xwalk_description']
165     elif 'xwalk_description' in self.data_src:
166       ret_dict['description'] = self.data_src['xwalk_description']
167     elif 'description' in self.data_src:
168       PrintDeprecationWarning('description')
169       ret_dict['description'] = self.data_src['description']
170     ret_dict['app_url'] = app_url
171     ret_dict['app_root'] = app_root
172     ret_dict['app_local_path'] = app_local_path
173     ret_dict['permissions'] = ''
174     if 'xwalk_permissions' in self.data_src:
175       try:
176         permission_list = self.data_src['xwalk_permissions']
177         ret_dict['permissions'] = HandlePermissionList(permission_list)
178       except (TypeError, ValueError, IOError):
179         print('\'Permissions\' field error in manifest.json file.')
180         sys.exit(1)
181     elif 'permissions' in self.data_src:
182       PrintDeprecationWarning('permissions')
183       try:
184         permission_list = self.data_src['permissions']
185         ret_dict['permissions'] = HandlePermissionList(permission_list)
186       except (TypeError, ValueError, IOError):
187         print('\'Permissions\' field error in manifest.json file.')
188         sys.exit(1)
189     orientation = {'landscape':'landscape',
190                    'landscape-primary':'landscape',
191                    'landscape-secondary':'reverseLandscape',
192                    'portrait':'portrait',
193                    'portrait-primary':'portrait',
194                    'portrait-secondary':'reversePortrait',
195                    'any':'unspecified',
196                    'natural':'unspecified'}
197     if 'orientation' in self.data_src:
198       if self.data_src['orientation'] in orientation:
199         ret_dict['orientation'] = orientation[self.data_src['orientation']]
200       else:
201         ret_dict['orientation'] = 'unspecified'
202     else:
203       ret_dict['orientation'] = 'unspecified'
204     if 'display' in self.data_src and 'fullscreen' in self.data_src['display']:
205       ret_dict['fullscreen'] = 'true'
206     else:
207       ret_dict['fullscreen'] = ''
208     if 'xwalk_launch_screen' in self.data_src:
209       launch_screen_dict = self.data_src['xwalk_launch_screen']
210       ParseLaunchScreen(ret_dict, launch_screen_dict, 'default')
211       ParseLaunchScreen(ret_dict, launch_screen_dict, 'portrait')
212       ParseLaunchScreen(ret_dict, launch_screen_dict, 'landscape')
213     elif 'launch_screen' in self.data_src:
214       PrintDeprecationWarning('launch_screen')
215       launch_screen_dict = self.data_src['launch_screen']
216       ParseLaunchScreen(ret_dict, launch_screen_dict, 'default')
217       ParseLaunchScreen(ret_dict, launch_screen_dict, 'portrait')
218       ParseLaunchScreen(ret_dict, launch_screen_dict, 'landscape')
219     return ret_dict
220
221   def ShowItems(self):
222     """Show the processed results, it is used for command-line
223     internal debugging."""
224     print("app_name: %s" % self.GetAppName())
225     print("version: %s" % self.GetVersion())
226     print("description: %s" % self.GetDescription())
227     print("icons: %s" % self.GetIcons())
228     print("app_url: %s" % self.GetAppUrl())
229     print("app_root: %s" % self.GetAppRoot())
230     print("app_local_path: %s" % self.GetAppLocalPath())
231     print("permissions: %s" % self.GetPermissions())
232     print("orientation: %s" % self.GetOrientation())
233     print("fullscreen: %s" % self.GetFullScreenFlag())
234     print('launch_screen.default.background_color: %s' %
235         self.GetLaunchScreenBackgroundColor('default'))
236     print('launch_screen.default.background_image: %s' %
237         self.GetLaunchScreenBackgroundImage('default'))
238     print('launch_screen.default.image: %s' %
239         self.GetLaunchScreenImage('default'))
240     print('launch_screen.default.image_border: %s' %
241         self.GetLaunchScreenImageBorder('default'))
242     print('launch_screen.portrait.background_color: %s' %
243         self.GetLaunchScreenBackgroundColor('portrait'))
244     print('launch_screen.portrait.background_image: %s' %
245         self.GetLaunchScreenBackgroundImage('portrait'))
246     print('launch_screen.portrait.image: %s' %
247         self.GetLaunchScreenImage('portrait'))
248     print('launch_screen.portrait.image_border: %s' %
249         self.GetLaunchScreenImageBorder('portrait'))
250     print('launch_screen.landscape.background_color: %s' %
251         self.GetLaunchScreenBackgroundColor('landscape'))
252     print('launch_screen.landscape.background_image: %s' %
253         self.GetLaunchScreenBackgroundImage('landscape'))
254     print('launch_screen.landscape.image: %s' %
255         self.GetLaunchScreenImage('landscape'))
256     print('launch_screen.landscape.image_border: %s' %
257         self.GetLaunchScreenImageBorder('landscape'))
258
259   def GetAppName(self):
260     """Return the application name."""
261     return self.ret_dict['app_name']
262
263   def GetVersion(self):
264     """Return the version number."""
265     return self.ret_dict['version']
266
267   def GetIcons(self):
268     """Return the icons."""
269     return self.ret_dict['icons']
270
271   def GetAppUrl(self):
272     """Return the URL of the application."""
273     return self.ret_dict['app_url']
274
275   def GetDescription(self):
276     """Return the description of the application."""
277     return self.ret_dict['description']
278
279   def GetAppRoot(self):
280     """Return the root path of the local web application."""
281     return self.ret_dict['app_root']
282
283   def GetAppLocalPath(self):
284     """Return the local relative path of the local web application."""
285     return self.ret_dict['app_local_path']
286
287   def GetPermissions(self):
288     """Return the permissions."""
289     return self.ret_dict['permissions']
290
291   def GetOrientation(self):
292     """Return the default allowed orientations"""
293     return self.ret_dict['orientation']
294
295   def GetFullScreenFlag(self):
296     """Return the set fullscreen flag of the application."""
297     return self.ret_dict['fullscreen']
298
299   def GetLaunchScreenBackgroundColor(self, orientation):
300     """Return the background color for launch_screen."""
301     key = 'launch_screen_background_color_' + orientation
302     return self.ret_dict.get(key, '')
303
304   def GetLaunchScreenBackgroundImage(self, orientation):
305     """Return the background image for launch_screen."""
306     key = 'launch_screen_background_image_' + orientation
307     return self.ret_dict.get(key, '')
308
309   def GetLaunchScreenImage(self, orientation):
310     """Return the image for launch_screen."""
311     key = 'launch_screen_image_' + orientation
312     return self.ret_dict.get(key, '')
313
314   def GetLaunchScreenImageBorder(self, orientation):
315     """Return the image border for launch_screen."""
316     key = 'launch_screen_image_border_' + orientation
317     return self.ret_dict.get(key, '')
318
319
320 def main(argv):
321   """Respond to command mode and show the processed field values."""
322   parser = optparse.OptionParser()
323   info = ('The input json-format file name. Such as: '
324           '--jsonfile=manifest.json')
325   parser.add_option('-j', '--jsonfile', action='store', dest='jsonfile',
326                     help=info)
327   opts, _ = parser.parse_args()
328   if len(argv) == 1:
329     parser.print_help()
330     return 0
331   json_parser = ManifestJsonParser(opts.jsonfile)
332   json_parser.ShowItems()
333   return 0
334
335
336 if __name__ == '__main__':
337   sys.exit(main(sys.argv))