@ -1,8 +0,0 @@ |
||||
fileFormatVersion: 2 |
||||
guid: 806e06ea7f4e7444fbee6a0d073d0a01 |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -1,24 +0,0 @@ |
||||
<!-- Copyright (C) 2019 Google Inc. All Rights Reserved. |
||||
|
||||
FirebaseApp iOS and Android Dependencies. |
||||
--> |
||||
|
||||
<dependencies> |
||||
<iosPods> |
||||
<iosPod name="Firebase/Core" version="10.3.0" minTargetSdk="8.0"> |
||||
</iosPod> |
||||
</iosPods> |
||||
<androidPackages> |
||||
<androidPackage spec="com.google.firebase:firebase-common:20.2.0"> |
||||
</androidPackage> |
||||
<androidPackage spec="com.google.firebase:firebase-analytics:21.2.0"> |
||||
</androidPackage> |
||||
<androidPackage spec="com.google.android.gms:play-services-base:18.1.0"> |
||||
</androidPackage> |
||||
<androidPackage spec="com.google.firebase:firebase-app-unity:10.3.0"> |
||||
<repositories> |
||||
<repository>Assets/Firebase/m2repository</repository> |
||||
</repositories> |
||||
</androidPackage> |
||||
</androidPackages> |
||||
</dependencies> |
@ -1,11 +0,0 @@ |
||||
fileFormatVersion: 2 |
||||
guid: 9b63af95d9364af4a3d8ce58738b6223 |
||||
labels: |
||||
- gvh |
||||
- gvh_version-10.3.0 |
||||
- gvhp_exportpath-Firebase/Editor/AppDependencies.xml |
||||
timeCreated: 1480838400 |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -1,22 +0,0 @@ |
||||
<!-- Copyright (C) 2019 Google Inc. All Rights Reserved. |
||||
|
||||
FirebaseAuth iOS and Android Dependencies. |
||||
--> |
||||
|
||||
<dependencies> |
||||
<iosPods> |
||||
<iosPod name="Firebase/Auth" version="10.3.0" minTargetSdk="8.0"> |
||||
</iosPod> |
||||
</iosPods> |
||||
<androidPackages> |
||||
<androidPackage spec="com.google.firebase:firebase-auth:21.1.0"> |
||||
</androidPackage> |
||||
<androidPackage spec="com.google.firebase:firebase-analytics:21.2.0"> |
||||
</androidPackage> |
||||
<androidPackage spec="com.google.firebase:firebase-auth-unity:10.3.0"> |
||||
<repositories> |
||||
<repository>Assets/Firebase/m2repository</repository> |
||||
</repositories> |
||||
</androidPackage> |
||||
</androidPackages> |
||||
</dependencies> |
@ -1,11 +0,0 @@ |
||||
fileFormatVersion: 2 |
||||
guid: 2bec2bf8d84d4997ba2dd66263781f3d |
||||
labels: |
||||
- gvh |
||||
- gvh_version-10.3.0 |
||||
- gvhp_exportpath-Firebase/Editor/AuthDependencies.xml |
||||
timeCreated: 1480838400 |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
Binary file not shown.
@ -1,118 +0,0 @@ |
||||
fileFormatVersion: 2 |
||||
guid: 9f2edbf81053418f879076c05f816dc2 |
||||
labels: |
||||
- gvh |
||||
- gvh_targets-editor |
||||
- gvh_version-10.3.0 |
||||
- gvhp_exportpath-Firebase/Editor/Firebase.Editor.dll |
||||
PluginImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
iconMap: {} |
||||
executionOrder: {} |
||||
defineConstraints: [] |
||||
isPreloaded: 0 |
||||
isOverridable: 0 |
||||
isExplicitlyReferenced: 0 |
||||
validateReferences: 1 |
||||
platformData: |
||||
- first: |
||||
: Linux |
||||
second: |
||||
enabled: 0 |
||||
settings: |
||||
CPU: None |
||||
- first: |
||||
: LinuxUniversal |
||||
second: |
||||
enabled: 0 |
||||
settings: |
||||
CPU: None |
||||
- first: |
||||
: OSXIntel |
||||
second: |
||||
enabled: 0 |
||||
settings: |
||||
CPU: None |
||||
- first: |
||||
: OSXIntel64 |
||||
second: |
||||
enabled: 0 |
||||
settings: |
||||
CPU: None |
||||
- first: |
||||
: Web |
||||
second: |
||||
enabled: 0 |
||||
settings: {} |
||||
- first: |
||||
: WebStreamed |
||||
second: |
||||
enabled: 0 |
||||
settings: {} |
||||
- first: |
||||
Android: Android |
||||
second: |
||||
enabled: 0 |
||||
settings: |
||||
CPU: AnyCPU |
||||
- first: |
||||
Any: |
||||
second: |
||||
enabled: 0 |
||||
settings: {} |
||||
- first: |
||||
Editor: Editor |
||||
second: |
||||
enabled: 1 |
||||
settings: |
||||
CPU: AnyCPU |
||||
DefaultValueInitialized: true |
||||
OS: AnyOS |
||||
- first: |
||||
Standalone: Linux64 |
||||
second: |
||||
enabled: 0 |
||||
settings: |
||||
CPU: None |
||||
- first: |
||||
Standalone: OSXUniversal |
||||
second: |
||||
enabled: 0 |
||||
settings: |
||||
CPU: None |
||||
- first: |
||||
Standalone: Win |
||||
second: |
||||
enabled: 0 |
||||
settings: |
||||
CPU: None |
||||
- first: |
||||
Standalone: Win64 |
||||
second: |
||||
enabled: 0 |
||||
settings: |
||||
CPU: None |
||||
- first: |
||||
Windows Store Apps: WindowsStoreApps |
||||
second: |
||||
enabled: 0 |
||||
settings: |
||||
CPU: AnyCPU |
||||
- first: |
||||
iPhone: iOS |
||||
second: |
||||
enabled: 0 |
||||
settings: |
||||
CompileFlags: |
||||
FrameworkDependencies: |
||||
- first: |
||||
tvOS: tvOS |
||||
second: |
||||
enabled: 0 |
||||
settings: |
||||
CompileFlags: |
||||
FrameworkDependencies: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
Binary file not shown.
@ -1,13 +0,0 @@ |
||||
fileFormatVersion: 2 |
||||
guid: f2ceb9c446ee4196b6476d4978a416b6 |
||||
labels: |
||||
- gvh |
||||
- gvh_rename_to_disable |
||||
- gvh_targets-editor |
||||
- gvh_version-10.3.0 |
||||
- gvhp_exportpath-Firebase/Editor/Firebase.Editor.pdb |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -1,71 +0,0 @@ |
||||
Assets/Editor Default Resources/Firebase/fb_analytics.png |
||||
Assets/Editor Default Resources/Firebase/fb_analytics_dark.png |
||||
Assets/Editor Default Resources/Firebase/fb_auth.png |
||||
Assets/Editor Default Resources/Firebase/fb_auth_dark.png |
||||
Assets/Editor Default Resources/Firebase/fb_cloud_messaging.png |
||||
Assets/Editor Default Resources/Firebase/fb_cloud_messaging_dark.png |
||||
Assets/Editor Default Resources/Firebase/fb_config.png |
||||
Assets/Editor Default Resources/Firebase/fb_config_dark.png |
||||
Assets/Editor Default Resources/Firebase/fb_crashlytics.png |
||||
Assets/Editor Default Resources/Firebase/fb_crashlytics_dark.png |
||||
Assets/Editor Default Resources/Firebase/fb_database.png |
||||
Assets/Editor Default Resources/Firebase/fb_database_dark.png |
||||
Assets/Editor Default Resources/Firebase/fb_dynamic_links.png |
||||
Assets/Editor Default Resources/Firebase/fb_dynamic_links_dark.png |
||||
Assets/Editor Default Resources/Firebase/fb_functions.png |
||||
Assets/Editor Default Resources/Firebase/fb_functions_dark.png |
||||
Assets/Editor Default Resources/Firebase/fb_invites.png |
||||
Assets/Editor Default Resources/Firebase/fb_invites_dark.png |
||||
Assets/Editor Default Resources/Firebase/fb_storage.png |
||||
Assets/Editor Default Resources/Firebase/fb_storage_dark.png |
||||
Assets/Editor Default Resources/Firebase/firebase_lockup.png |
||||
Assets/Editor Default Resources/Firebase/firebase_lockup_dark.png |
||||
Assets/ExternalDependencyManager/Editor/1.2.175/Google.IOSResolver.dll |
||||
Assets/ExternalDependencyManager/Editor/1.2.175/Google.IOSResolver.dll.mdb |
||||
Assets/ExternalDependencyManager/Editor/1.2.175/Google.JarResolver.dll |
||||
Assets/ExternalDependencyManager/Editor/1.2.175/Google.JarResolver.dll.mdb |
||||
Assets/ExternalDependencyManager/Editor/1.2.175/Google.PackageManagerResolver.dll |
||||
Assets/ExternalDependencyManager/Editor/1.2.175/Google.PackageManagerResolver.dll.mdb |
||||
Assets/ExternalDependencyManager/Editor/1.2.175/Google.VersionHandlerImpl.dll |
||||
Assets/ExternalDependencyManager/Editor/1.2.175/Google.VersionHandlerImpl.dll.mdb |
||||
Assets/ExternalDependencyManager/Editor/CHANGELOG.md |
||||
Assets/ExternalDependencyManager/Editor/Google.VersionHandler.dll |
||||
Assets/ExternalDependencyManager/Editor/Google.VersionHandler.dll.mdb |
||||
Assets/ExternalDependencyManager/Editor/LICENSE |
||||
Assets/ExternalDependencyManager/Editor/README.md |
||||
Assets/ExternalDependencyManager/Editor/external-dependency-manager_version-1.2.175_manifest.txt |
||||
Assets/Firebase/Editor/AppDependencies.xml |
||||
Assets/Firebase/Editor/AuthDependencies.xml |
||||
Assets/Firebase/Editor/Firebase.Editor.dll |
||||
Assets/Firebase/Editor/Firebase.Editor.pdb |
||||
Assets/Firebase/Editor/generate_xml_from_google_services_json.exe |
||||
Assets/Firebase/Editor/generate_xml_from_google_services_json.py |
||||
Assets/Firebase/Editor/network_request.exe |
||||
Assets/Firebase/Editor/network_request.py |
||||
Assets/Firebase/Plugins/Firebase.App.dll |
||||
Assets/Firebase/Plugins/Firebase.App.pdb |
||||
Assets/Firebase/Plugins/Firebase.Auth.dll |
||||
Assets/Firebase/Plugins/Firebase.Auth.pdb |
||||
Assets/Firebase/Plugins/Firebase.Platform.dll |
||||
Assets/Firebase/Plugins/Firebase.Platform.pdb |
||||
Assets/Firebase/Plugins/Firebase.TaskExtension.dll |
||||
Assets/Firebase/Plugins/Firebase.TaskExtension.pdb |
||||
Assets/Firebase/Plugins/Google.MiniJson.dll |
||||
Assets/Firebase/Plugins/iOS/Firebase.App.dll |
||||
Assets/Firebase/Plugins/iOS/Firebase.App.pdb |
||||
Assets/Firebase/Plugins/iOS/Firebase.Auth.dll |
||||
Assets/Firebase/Plugins/iOS/Firebase.Auth.pdb |
||||
Assets/Firebase/Plugins/x86_64/FirebaseCppApp-10_3_0.bundle |
||||
Assets/Firebase/Plugins/x86_64/FirebaseCppApp-10_3_0.dll |
||||
Assets/Firebase/Plugins/x86_64/FirebaseCppApp-10_3_0.so |
||||
Assets/Firebase/Plugins/x86_64/FirebaseCppAuth.bundle |
||||
Assets/Firebase/Plugins/x86_64/FirebaseCppAuth.dll |
||||
Assets/Firebase/Plugins/x86_64/FirebaseCppAuth.so |
||||
Assets/Firebase/m2repository/com/google/firebase/firebase-app-unity/10.3.0/firebase-app-unity-10.3.0.pom |
||||
Assets/Firebase/m2repository/com/google/firebase/firebase-app-unity/10.3.0/firebase-app-unity-10.3.0.srcaar |
||||
Assets/Firebase/m2repository/com/google/firebase/firebase-app-unity/maven-metadata.xml |
||||
Assets/Firebase/m2repository/com/google/firebase/firebase-auth-unity/10.3.0/firebase-auth-unity-10.3.0.pom |
||||
Assets/Firebase/m2repository/com/google/firebase/firebase-auth-unity/10.3.0/firebase-auth-unity-10.3.0.srcaar |
||||
Assets/Firebase/m2repository/com/google/firebase/firebase-auth-unity/maven-metadata.xml |
||||
Assets/Plugins/iOS/Firebase/libFirebaseCppApp.a |
||||
Assets/Plugins/iOS/Firebase/libFirebaseCppAuth.a |
@ -1,10 +0,0 @@ |
||||
fileFormatVersion: 2 |
||||
guid: e7c782cb27424ab6a09499e9edde5994 |
||||
labels: |
||||
- gvh |
||||
- gvh_manifest |
||||
- gvh_version-10.3.0 |
||||
- gvhp_exportpath-Firebase/Editor/FirebaseAuth_version-10.3.0_manifest.txt |
||||
- gvhp_manifestname-0Firebase Authentication |
||||
- gvhp_manifestname-1FirebaseAuth |
||||
timeCreated: 0 |
Binary file not shown.
@ -1,11 +0,0 @@ |
||||
fileFormatVersion: 2 |
||||
guid: ae88c0972b7448b5b36def1716f1d711 |
||||
labels: |
||||
- gvh |
||||
- gvh_version-10.3.0 |
||||
- gvhp_exportpath-Firebase/Editor/generate_xml_from_google_services_json.exe |
||||
timeCreated: 1480838400 |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -1,496 +0,0 @@ |
||||
#!/usr/bin/python |
||||
|
||||
# Copyright 2016 Google LLC |
||||
# |
||||
# Licensed 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. |
||||
|
||||
"""Stand-alone implementation of the Gradle Firebase plugin. |
||||
|
||||
Converts the services json file to xml: |
||||
https://googleplex-android.googlesource.com/platform/tools/base/+/studio-master-dev/build-system/google-services/src/main/groovy/com/google/gms/googleservices |
||||
""" |
||||
|
||||
__author__ = 'Wouter van Oortmerssen' |
||||
|
||||
import argparse |
||||
import ctypes |
||||
import json |
||||
import os |
||||
import platform |
||||
import sys |
||||
from xml.etree import ElementTree |
||||
|
||||
if platform.system().lower() == 'windows': |
||||
import ctypes.wintypes # pylint: disable=g-import-not-at-top |
||||
|
||||
# Map Python 2's unicode method to encode a string as bytes in python 3. |
||||
try: |
||||
unicode('') # See whether unicode class is available (Python < 3) |
||||
except NameError: |
||||
unicode = str # pylint: disable=redefined-builtin,invalid-name |
||||
|
||||
# Input filename if it isn't set. |
||||
DEFAULT_INPUT_FILENAME = 'app/google-services.json' |
||||
# Output filename if it isn't set. |
||||
DEFAULT_OUTPUT_FILENAME = 'res/values/googleservices.xml' |
||||
# Input filename for .plist files, if it isn't set. |
||||
DEFAULT_PLIST_INPUT_FILENAME = 'GoogleService-Info.plist' |
||||
# Output filename for .json files, if it isn't set. |
||||
DEFAULT_JSON_OUTPUT_FILENAME = 'google-services-desktop.json' |
||||
|
||||
OAUTH_CLIENT_TYPE_ANDROID_APP = 1 |
||||
OAUTH_CLIENT_TYPE_WEB = 3 |
||||
|
||||
|
||||
def read_xml_value(xml_node): |
||||
"""Utility method for reading values from the plist XML. |
||||
|
||||
Args: |
||||
xml_node: An ElementTree node, that contains a value. |
||||
|
||||
Returns: |
||||
The value of the node, or None, if it could not be read. |
||||
""" |
||||
if xml_node.tag == 'string': |
||||
return xml_node.text |
||||
elif xml_node.tag == 'integer': |
||||
return int(xml_node.text) |
||||
elif xml_node.tag == 'real': |
||||
return float(xml_node.text) |
||||
elif xml_node.tag == 'false': |
||||
return 0 |
||||
elif xml_node.tag == 'true': |
||||
return 1 |
||||
else: |
||||
# other types of input are ignored. (data, dates, arrays, etc.) |
||||
return None |
||||
|
||||
|
||||
def construct_plist_dictionary(xml_root): |
||||
"""Constructs a dictionary of values based on the contents of a plist file. |
||||
|
||||
Args: |
||||
xml_root: An ElementTree node, that represents the root of the xml file |
||||
that is to be parsed. (Which should be a dictionary containing |
||||
key-value pairs of the properties that need to be extracted.) |
||||
|
||||
Returns: |
||||
A dictionary, containing key-value pairs for all (supported) entries in the |
||||
node. |
||||
""" |
||||
xml_dict = xml_root.find('dict') |
||||
|
||||
if xml_dict is None: |
||||
return None |
||||
|
||||
plist_dict = {} |
||||
i = 0 |
||||
while i < len(xml_dict): |
||||
if xml_dict[i].tag == 'key': |
||||
key = xml_dict[i].text |
||||
i += 1 |
||||
if i < len(xml_dict): |
||||
value = read_xml_value(xml_dict[i]) |
||||
if value is not None: |
||||
plist_dict[key] = value |
||||
i += 1 |
||||
|
||||
return plist_dict |
||||
|
||||
|
||||
def update_dict_keys(key_map, input_dict): |
||||
"""Creates a dict from input_dict with the same values but new keys. |
||||
|
||||
Two dictionaries are passed to this function: the key_map that represents a |
||||
mapping of source keys to destination keys, and the input_dict that is the |
||||
dictionary that is to be duplicated, replacing any key that matches a source |
||||
key with a destination key. Source keys that are not present in the |
||||
input_dict will not have their destination key represented in the result. |
||||
|
||||
In other words, if key_map is `{'old': 'new', 'foo': 'bar'}`, and input_dict |
||||
is `{'old': 10}`, the result will be `{'new': 10}`. |
||||
|
||||
Args: |
||||
key_map (dict): A dictionary of strings to strings that maps source keys to |
||||
destination keys. |
||||
input_dict (dict): The dictionary of string keys to any value type, which |
||||
is to be duplicated, replacing source keys with the corresponding |
||||
destination keys from key_map. |
||||
|
||||
Returns: |
||||
dict: A new dictionary with updated keys. |
||||
""" |
||||
return { |
||||
new_key: input_dict[old_key] |
||||
for (old_key, new_key) in key_map.items() |
||||
if old_key in input_dict |
||||
} |
||||
|
||||
|
||||
def construct_google_services_json(xml_dict): |
||||
"""Constructs a google services json file from a dictionary. |
||||
|
||||
Args: |
||||
xml_dict: A dictionary of all the key/value pairs that are needed for the |
||||
output json file. |
||||
Returns: |
||||
A string representing the output json file. |
||||
""" |
||||
|
||||
try: |
||||
json_struct = { |
||||
'project_info': |
||||
update_dict_keys( |
||||
{ |
||||
'GCM_SENDER_ID': 'project_number', |
||||
'DATABASE_URL': 'firebase_url', |
||||
'PROJECT_ID': 'project_id', |
||||
'STORAGE_BUCKET': 'storage_bucket' |
||||
}, xml_dict), |
||||
'client': [{ |
||||
'client_info': { |
||||
'mobilesdk_app_id': xml_dict['GOOGLE_APP_ID'], |
||||
'android_client_info': { |
||||
'package_name': xml_dict['BUNDLE_ID'] |
||||
} |
||||
}, |
||||
'oauth_client': [{ |
||||
'client_id': xml_dict['CLIENT_ID'], |
||||
}], |
||||
'api_key': [{ |
||||
'current_key': xml_dict['API_KEY'] |
||||
}], |
||||
'services': { |
||||
'analytics_service': { |
||||
'status': xml_dict['IS_ANALYTICS_ENABLED'] |
||||
}, |
||||
'appinvite_service': { |
||||
'status': xml_dict['IS_APPINVITE_ENABLED'] |
||||
} |
||||
} |
||||
},], |
||||
'configuration_version': |
||||
'1' |
||||
} |
||||
return json.dumps(json_struct, indent=2) |
||||
except KeyError as e: |
||||
sys.stderr.write('Could not find key in plist file: [%s]\n' % (e.args[0])) |
||||
return None |
||||
|
||||
|
||||
def convert_plist_to_json(plist_string, input_filename): |
||||
"""Converts an input plist string into a .json file and saves it. |
||||
|
||||
Args: |
||||
plist_string: The contents of the loaded plist file. |
||||
|
||||
input_filename: The file name that the plist data was read from. |
||||
Returns: |
||||
the converted string, or None if there were errors. |
||||
""" |
||||
|
||||
try: |
||||
root = ElementTree.fromstring(plist_string) |
||||
except ElementTree.ParseError: |
||||
sys.stderr.write('Error parsing file %s.\n' |
||||
'It does not appear to be valid XML.\n' % (input_filename)) |
||||
return None |
||||
|
||||
plist_dict = construct_plist_dictionary(root) |
||||
if plist_dict is None: |
||||
sys.stderr.write('In file %s, could not locate a top-level \'dict\' ' |
||||
'element.\n' |
||||
'File format should be plist XML, with a top-level ' |
||||
'dictionary containing project settings as key-value ' |
||||
'pairs.\n' % (input_filename)) |
||||
return None |
||||
|
||||
json_string = construct_google_services_json(plist_dict) |
||||
return json_string |
||||
|
||||
|
||||
def gen_string(parent, name, text): |
||||
"""Generate one <string /> element and put into the list of keeps. |
||||
|
||||
Args: |
||||
parent: The object that will hold the string. |
||||
name: The name to store the string under. |
||||
text: The text of the string. |
||||
""" |
||||
if text: |
||||
prev = parent.get('tools:keep', '') |
||||
if prev: |
||||
prev += ',' |
||||
parent.set('tools:keep', prev + '@string/' + name) |
||||
child = ElementTree.SubElement(parent, 'string', { |
||||
'name': name, |
||||
'translatable': 'false' |
||||
}) |
||||
child.text = text |
||||
|
||||
|
||||
def indent(elem, level=0): |
||||
"""Recurse through XML tree and add indentation. |
||||
|
||||
Args: |
||||
elem: The element to recurse over |
||||
level: The current indentation level. |
||||
""" |
||||
i = '\n' + level*' ' |
||||
if elem is not None: |
||||
if not elem.text or not elem.text.strip(): |
||||
elem.text = i + ' ' |
||||
if not elem.tail or not elem.tail.strip(): |
||||
elem.tail = i |
||||
for elem in elem: |
||||
indent(elem, level+1) |
||||
if not elem.tail or not elem.tail.strip(): |
||||
elem.tail = i |
||||
else: |
||||
if level and (not elem.tail or not elem.tail.strip()): |
||||
elem.tail = i |
||||
|
||||
|
||||
def argv_as_unicode_win32(): |
||||
"""Returns unicode command line arguments on windows. |
||||
""" |
||||
|
||||
get_command_line_w = ctypes.cdll.kernel32.GetCommandLineW |
||||
get_command_line_w.restype = ctypes.wintypes.LPCWSTR |
||||
|
||||
# CommandLineToArgvW parses the Unicode command line |
||||
command_line_to_argv_w = ctypes.windll.shell32.CommandLineToArgvW |
||||
command_line_to_argv_w.argtypes = [ |
||||
ctypes.wintypes.LPCWSTR, |
||||
ctypes.POINTER(ctypes.c_int) |
||||
] |
||||
command_line_to_argv_w.restype = ctypes.POINTER( |
||||
ctypes.wintypes.LPWSTR) |
||||
|
||||
argc = ctypes.c_int(0) |
||||
argv = command_line_to_argv_w(get_command_line_w(), argc) |
||||
|
||||
# Strip the python executable from the arguments if it exists |
||||
# (It would be listed as the first argument on the windows command line, but |
||||
# not in the arguments to the python script) |
||||
sys_argv_len = len(sys.argv) |
||||
return [unicode(argv[i]) for i in |
||||
range(argc.value - sys_argv_len, argc.value)] |
||||
|
||||
|
||||
def main(): |
||||
parser = argparse.ArgumentParser( |
||||
description=(( |
||||
'Converts a Firebase %s into %s similar to the Gradle plugin, or ' |
||||
'converts a Firebase %s into a %s suitible for use on desktop apps.' % |
||||
(DEFAULT_INPUT_FILENAME, DEFAULT_OUTPUT_FILENAME, |
||||
DEFAULT_PLIST_INPUT_FILENAME, DEFAULT_JSON_OUTPUT_FILENAME)))) |
||||
parser.add_argument('-i', help='Override input file name', |
||||
metavar='FILE', required=False) |
||||
parser.add_argument('-o', help='Override destination file name', |
||||
metavar='FILE', required=False) |
||||
parser.add_argument('-p', help=('Package ID to select within the set of ' |
||||
'packages in the input file. If this is ' |
||||
'not specified, the first package in the ' |
||||
'input file is selected.')) |
||||
parser.add_argument('-l', help=('List all package IDs referenced by the ' |
||||
'input file. If this is specified, ' |
||||
'the output file is not created.'), |
||||
action='store_true', default=False, required=False) |
||||
parser.add_argument('-f', help=('Print project fields from the input file ' |
||||
'in the form \'name=value\\n\' for each ' |
||||
'field. If this is specified, the output ' |
||||
'is not created.'), |
||||
action='store_true', default=False, required=False) |
||||
parser.add_argument( |
||||
'--plist', |
||||
help=( |
||||
'Specifies a plist file to convert to a JSON configuration file. ' |
||||
'If this is enabled, the script will expect a .plist file as input, ' |
||||
'which it will convert into %s file. The output file is ' |
||||
'*not* suitable for use with Firebase on Android.' % |
||||
(DEFAULT_JSON_OUTPUT_FILENAME)), |
||||
action='store_true', |
||||
default=False, |
||||
required=False) |
||||
|
||||
# python 2 on Windows doesn't handle unicode arguments well, so we need to |
||||
# pre-process the command line arguments before trying to parse them. |
||||
if platform.system() == 'Windows': |
||||
sys.argv = argv_as_unicode_win32() |
||||
|
||||
args = parser.parse_args() |
||||
|
||||
if args.plist: |
||||
input_filename = DEFAULT_PLIST_INPUT_FILENAME |
||||
output_filename = DEFAULT_JSON_OUTPUT_FILENAME |
||||
else: |
||||
input_filename = DEFAULT_INPUT_FILENAME |
||||
output_filename = DEFAULT_OUTPUT_FILENAME |
||||
|
||||
if args.i: |
||||
# Encode the input string (type unicode) as a normal string (type str) |
||||
# using the 'utf-8' encoding so that it can be worked with the same as |
||||
# input names from other sources (like the defaults). |
||||
input_filename_raw = args.i.encode('utf-8') |
||||
# Decode the filename to a unicode string using the 'utf-8' encoding to |
||||
# properly handle filepaths with unicode characters in them. |
||||
input_filename = input_filename_raw.decode('utf-8') |
||||
|
||||
if args.o: |
||||
output_filename = args.o |
||||
|
||||
with open(input_filename, 'r') as ifile: |
||||
file_string = ifile.read() |
||||
|
||||
json_string = None |
||||
if args.plist: |
||||
json_string = convert_plist_to_json(file_string, input_filename) |
||||
if json_string is None: |
||||
return 1 |
||||
jsobj = json.loads(json_string) |
||||
else: |
||||
jsobj = json.loads(file_string) |
||||
|
||||
root = ElementTree.Element('resources') |
||||
root.set('xmlns:tools', 'http://schemas.android.com/tools') |
||||
|
||||
project_info = jsobj.get('project_info') |
||||
if project_info: |
||||
gen_string(root, 'firebase_database_url', project_info.get('firebase_url')) |
||||
gen_string(root, 'gcm_defaultSenderId', project_info.get('project_number')) |
||||
gen_string(root, 'google_storage_bucket', |
||||
project_info.get('storage_bucket')) |
||||
gen_string(root, 'project_id', project_info.get('project_id')) |
||||
|
||||
if args.f: |
||||
if not project_info: |
||||
sys.stderr.write('No project info found in %s.' % input_filename) |
||||
return 1 |
||||
for field, value in sorted(project_info.items()): |
||||
sys.stdout.write('%s=%s\n' % (field, value)) |
||||
return 0 |
||||
|
||||
packages = set() |
||||
client_list = jsobj.get('client') |
||||
if client_list: |
||||
# Search for the user specified package in the file. |
||||
selected_package_name = '' |
||||
selected_client = client_list[0] |
||||
find_package_name = args.p |
||||
for client in client_list: |
||||
package_name = client.get('client_info', {}).get( |
||||
'android_client_info', {}).get('package_name', '') |
||||
if not package_name: |
||||
package_name = client.get('oauth_client', {}).get( |
||||
'android_info', {}).get('package_name', '') |
||||
if package_name: |
||||
if not selected_package_name: |
||||
selected_package_name = package_name |
||||
selected_client = client |
||||
if package_name == find_package_name: |
||||
selected_package_name = package_name |
||||
selected_client = client |
||||
packages.add(package_name) |
||||
|
||||
if args.p and selected_package_name != find_package_name: |
||||
sys.stderr.write('No packages found in %s which match the package ' |
||||
'name %s\n' |
||||
'\n' |
||||
'Found the following:\n' |
||||
'%s\n' % (input_filename, find_package_name, |
||||
'\n'.join(packages))) |
||||
return 1 |
||||
|
||||
client_api_key = selected_client.get('api_key') |
||||
if client_api_key: |
||||
client_api_key0 = client_api_key[0] |
||||
gen_string(root, 'google_api_key', client_api_key0.get('current_key')) |
||||
gen_string(root, 'google_crash_reporting_api_key', |
||||
client_api_key0.get('current_key')) |
||||
|
||||
client_info = selected_client.get('client_info') |
||||
if client_info: |
||||
gen_string(root, 'google_app_id', client_info.get('mobilesdk_app_id')) |
||||
|
||||
# Only include the first matching OAuth client ID per type. |
||||
client_id_web_parsed = False |
||||
client_id_android_parsed = False |
||||
|
||||
oauth_client_list = selected_client.get('oauth_client') |
||||
if oauth_client_list: |
||||
for oauth_client in oauth_client_list: |
||||
client_type = oauth_client.get('client_type') |
||||
client_id = oauth_client.get('client_id') |
||||
if not (client_type and client_id): continue |
||||
if (client_type == OAUTH_CLIENT_TYPE_WEB and |
||||
not client_id_web_parsed): |
||||
gen_string(root, 'default_web_client_id', client_id) |
||||
client_id_web_parsed = True |
||||
if (client_type == OAUTH_CLIENT_TYPE_ANDROID_APP and |
||||
not client_id_android_parsed): |
||||
gen_string(root, 'default_android_client_id', client_id) |
||||
client_id_android_parsed = True |
||||
|
||||
services = selected_client.get('services') |
||||
if services: |
||||
ads_service = services.get('ads_service') |
||||
if ads_service: |
||||
gen_string(root, 'test_banner_ad_unit_id', |
||||
ads_service.get('test_banner_ad_unit_id')) |
||||
gen_string(root, 'test_interstitial_ad_unit_id', |
||||
ads_service.get('test_interstitial_ad_unit_id')) |
||||
analytics_service = services.get('analytics_service') |
||||
if analytics_service: |
||||
analytics_property = analytics_service.get('analytics_property') |
||||
if analytics_property: |
||||
gen_string(root, 'ga_trackingId', |
||||
analytics_property.get('tracking_id')) |
||||
# enable this once we have an example if this service being present |
||||
# in the json data: |
||||
maps_service_enabled = False |
||||
if maps_service_enabled: |
||||
maps_service = services.get('maps_service') |
||||
if maps_service: |
||||
maps_api_key = maps_service.get('api_key') |
||||
if maps_api_key: |
||||
for k in range(0, len(maps_api_key)): |
||||
# generates potentially multiple of these keys, which is |
||||
# the same behavior as the java plugin. |
||||
gen_string(root, 'google_maps_key', |
||||
maps_api_key[k].get('maps_api_key')) |
||||
|
||||
tree = ElementTree.ElementTree(root) |
||||
|
||||
indent(root) |
||||
|
||||
if args.l: |
||||
for package in sorted(packages): |
||||
if package: |
||||
sys.stdout.write(package + '\n') |
||||
else: |
||||
path = os.path.dirname(output_filename) |
||||
|
||||
if path and not os.path.exists(path): |
||||
os.makedirs(path) |
||||
|
||||
if not args.plist: |
||||
tree.write(output_filename, 'utf-8', True) |
||||
else: |
||||
with open(output_filename, 'w') as ofile: |
||||
ofile.write(json_string) |
||||
|
||||
return 0 |
||||
|
||||
if __name__ == '__main__': |
||||
sys.exit(main()) |
@ -1,11 +0,0 @@ |
||||
fileFormatVersion: 2 |
||||
guid: 8f18ed76c0f04ce0a65736104f913ef8 |
||||
labels: |
||||
- gvh |
||||
- gvh_version-10.3.0 |
||||
- gvhp_exportpath-Firebase/Editor/generate_xml_from_google_services_json.py |
||||
timeCreated: 1480838400 |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
Binary file not shown.
@ -1,11 +0,0 @@ |
||||
fileFormatVersion: 2 |
||||
guid: d3cd5d0a941c4cdc8ab4b1b684b05191 |
||||
labels: |
||||
- gvh |
||||
- gvh_version-10.3.0 |
||||
- gvhp_exportpath-Firebase/Editor/network_request.exe |
||||
timeCreated: 1480838400 |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -1,416 +0,0 @@ |
||||
# Copyright 2019 Google LLC |
||||
# |
||||
# Licensed 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. |
||||
"""Wrapper script which makes a network request. |
||||
|
||||
Basic Usage: network_request.py post |
||||
--url <url> |
||||
--header <header> (optional, support multiple) |
||||
--body <body> (optional) |
||||
--timeout <secs> (optional) |
||||
--verbose (optional) |
||||
""" |
||||
|
||||
import argparse |
||||
import inspect |
||||
import logging |
||||
import socket |
||||
import sys |
||||
|
||||
# pylint: disable=g-import-not-at-top |
||||
# pylint: disable=g-importing-member |
||||
try: |
||||
from six.moves.http_client import HTTPSConnection |
||||
from six.moves.http_client import HTTPConnection |
||||
from six.moves.http_client import HTTPException |
||||
except ImportError: |
||||
from http.client import HTTPSConnection |
||||
from http.client import HTTPConnection |
||||
from http.client import HTTPException |
||||
|
||||
try: |
||||
from six.moves.urllib.parse import urlparse |
||||
except ImportError: |
||||
from urllib.parse import urlparse |
||||
# pylint: enable=g-import-not-at-top |
||||
# pylint: enable=g-importing-member |
||||
|
||||
# Set up logger as soon as possible |
||||
formatter = logging.Formatter('[%(levelname)s] %(message)s') |
||||
|
||||
handler = logging.StreamHandler(stream=sys.stdout) |
||||
handler.setFormatter(formatter) |
||||
handler.setLevel(logging.INFO) |
||||
|
||||
logger = logging.getLogger(__name__) |
||||
logger.addHandler(handler) |
||||
logger.setLevel(logging.INFO) |
||||
|
||||
# Custom exit codes for known issues. |
||||
# System exit codes in python are valid from 0 - 256, so we will map some common |
||||
# ones here to understand successes and failures. |
||||
# Uses lower ints to not collide w/ HTTP status codes that the script may return |
||||
EXIT_CODE_SUCCESS = 0 |
||||
EXIT_CODE_SYS_ERROR = 1 |
||||
EXIT_CODE_INVALID_REQUEST_VALUES = 2 |
||||
EXIT_CODE_GENERIC_HTTPLIB_ERROR = 3 |
||||
EXIT_CODE_HTTP_TIMEOUT = 4 |
||||
EXIT_CODE_HTTP_REDIRECT_ERROR = 5 |
||||
EXIT_CODE_HTTP_NOT_FOUND_ERROR = 6 |
||||
EXIT_CODE_HTTP_SERVER_ERROR = 7 |
||||
EXIT_CODE_HTTP_UNKNOWN_ERROR = 8 |
||||
|
||||
MAX_EXIT_CODE = 8 |
||||
|
||||
# All used http verbs |
||||
POST = 'POST' |
||||
|
||||
|
||||
def unwrap_kwarg_namespace(func): |
||||
"""Transform a Namespace object from argparse into proper args and kwargs. |
||||
|
||||
For a function that will be delegated to from argparse, inspect all of the |
||||
argments and extract them from the Namespace object. |
||||
|
||||
Args: |
||||
func: the function that we are wrapping to modify behavior |
||||
|
||||
Returns: |
||||
a new function that unwraps all of the arguments in a namespace and then |
||||
delegates to the passed function with those args. |
||||
""" |
||||
# When we move to python 3, getfullargspec so that we can tell the |
||||
# difference between args and kwargs -- then this could be used for functions |
||||
# that have both args and kwargs |
||||
if 'getfullargspec' in dir(inspect): |
||||
argspec = inspect.getfullargspec(func) |
||||
else: |
||||
argspec = inspect.getargspec(func) # Python 2 compatibility. |
||||
|
||||
def wrapped(argparse_namespace=None, **kwargs): |
||||
"""Take a Namespace object and map it to kwargs. |
||||
|
||||
Inspect the argspec of the passed function. Loop over all the args that |
||||
are present in the function and try to map them by name to arguments in the |
||||
namespace. For keyword arguments, we do not require that they be present |
||||
in the Namespace. |
||||
|
||||
Args: |
||||
argparse_namespace: an arparse.Namespace object, the result of calling |
||||
argparse.ArgumentParser().parse_args() |
||||
**kwargs: keyword arguments that may be passed to the original function |
||||
Returns: |
||||
The return of the wrapped function from the parent. |
||||
|
||||
Raises: |
||||
ValueError in the event that an argument is passed to the cli that is not |
||||
in the set of named kwargs |
||||
""" |
||||
if not argparse_namespace: |
||||
return func(**kwargs) |
||||
|
||||
reserved_namespace_keywords = ['func'] |
||||
new_kwargs = {} |
||||
|
||||
args = argspec.args or [] |
||||
for arg_name in args: |
||||
passed_value = getattr(argparse_namespace, arg_name, None) |
||||
if passed_value is not None: |
||||
new_kwargs[arg_name] = passed_value |
||||
|
||||
for namespace_key in vars(argparse_namespace).keys(): |
||||
# ignore namespace keywords that have been set not passed in via cli |
||||
if namespace_key in reserved_namespace_keywords: |
||||
continue |
||||
|
||||
# make sure that we haven't passed something we should be processing |
||||
if namespace_key not in args: |
||||
raise ValueError('CLI argument "{}" does not match any argument in ' |
||||
'function {}'.format(namespace_key, func.__name__)) |
||||
|
||||
return func(**new_kwargs) |
||||
|
||||
wrapped.__name__ = func.__name__ |
||||
return wrapped |
||||
|
||||
|
||||
class NetworkRequest(object): |
||||
"""A container for an network request object. |
||||
|
||||
This class holds on to all of the attributes necessary for making a |
||||
network request via httplib. |
||||
""" |
||||
|
||||
def __init__(self, url, method, headers, body, timeout): |
||||
self.url = url.lower() |
||||
self.parsed_url = urlparse(self.url) |
||||
self.method = method |
||||
self.headers = headers |
||||
self.body = body |
||||
self.timeout = timeout |
||||
self.is_secure_connection = self.is_secure_connection() |
||||
|
||||
def execute_request(self): |
||||
""""Execute the request, and get a response. |
||||
|
||||
Returns: |
||||
an HttpResponse object from httplib |
||||
""" |
||||
if self.is_secure_connection: |
||||
conn = HTTPSConnection(self.get_hostname(), timeout=self.timeout) |
||||
else: |
||||
conn = HTTPConnection(self.get_hostname(), timeout=self.timeout) |
||||
|
||||
conn.request(self.method, self.url, self.body, self.headers) |
||||
response = conn.getresponse() |
||||
return response |
||||
|
||||
def get_hostname(self): |
||||
"""Return the hostname for the url.""" |
||||
return self.parsed_url.netloc |
||||
|
||||
def is_secure_connection(self): |
||||
"""Checks for a secure connection of https. |
||||
|
||||
Returns: |
||||
True if the scheme is "https"; False if "http" |
||||
|
||||
Raises: |
||||
ValueError when the scheme does not match http or https |
||||
""" |
||||
scheme = self.parsed_url.scheme |
||||
|
||||
if scheme == 'http': |
||||
return False |
||||
elif scheme == 'https': |
||||
return True |
||||
else: |
||||
raise ValueError('The url scheme is not "http" nor "https"' |
||||
': {}'.format(scheme)) |
||||
|
||||
|
||||
def parse_colon_delimited_options(option_args): |
||||
"""Parses a key value from a string. |
||||
|
||||
Args: |
||||
option_args: Key value string delimited by a color, ex: ("key:value") |
||||
|
||||
Returns: |
||||
Return an array with the key as the first element and value as the second |
||||
|
||||
Raises: |
||||
ValueError: If the key value option is not formatted correctly |
||||
""" |
||||
options = {} |
||||
|
||||
if not option_args: |
||||
return options |
||||
|
||||
for single_arg in option_args: |
||||
values = single_arg.split(':') |
||||
if len(values) != 2: |
||||
raise ValueError('An option arg must be a single key/value pair ' |
||||
'delimited by a colon - ex: "thing_key:thing_value"') |
||||
|
||||
key = values[0].strip() |
||||
value = values[1].strip() |
||||
options[key] = value |
||||
|
||||
return options |
||||
|
||||
|
||||
def make_request(request): |
||||
"""Makes a synchronous network request and return the HTTP status code. |
||||
|
||||
Args: |
||||
request: a well formulated request object |
||||
|
||||
Returns: |
||||
The HTTP status code of the network request. |
||||
'1' maps to invalid request headers. |
||||
""" |
||||
|
||||
logger.info('Sending network request -') |
||||
logger.info('\tUrl: %s', request.url) |
||||
logger.debug('\tMethod: %s', request.method) |
||||
logger.debug('\tHeaders: %s', request.headers) |
||||
logger.debug('\tBody: %s', request.body) |
||||
|
||||
try: |
||||
response = request.execute_request() |
||||
except socket.timeout: |
||||
logger.exception( |
||||
'Timed out post request to %s in %d seconds for request body: %s', |
||||
request.url, request.timeout, request.body) |
||||
return EXIT_CODE_HTTP_TIMEOUT |
||||
except (HTTPException, socket.error): |
||||
logger.exception( |
||||
'Encountered generic exception in posting to %s with request body %s', |
||||
request.url, request.body) |
||||
return EXIT_CODE_GENERIC_HTTPLIB_ERROR |
||||
|
||||
status = response.status |
||||
headers = response.getheaders() |
||||
logger.info('Received Network response -') |
||||
logger.info('\tStatus code: %d', status) |
||||
logger.debug('\tResponse headers: %s', headers) |
||||
|
||||
if status < 200 or status > 299: |
||||
logger.error('Request (%s) failed with status code %d\n', request.url, |
||||
status) |
||||
|
||||
# If we wanted this script to support get, we need to |
||||
# figure out what mechanism we intend for capturing the response |
||||
return status |
||||
|
||||
|
||||
@unwrap_kwarg_namespace |
||||
def post(url=None, header=None, body=None, timeout=5, verbose=False): |
||||
"""Sends a post request. |
||||
|
||||
Args: |
||||
url: The url of the request |
||||
header: A list of headers for the request |
||||
body: The body for the request |
||||
timeout: Timeout in seconds for the request |
||||
verbose: Should debug logs be displayed |
||||
|
||||
Returns: |
||||
Return an array with the key as the first element and value as the second |
||||
""" |
||||
|
||||
if verbose: |
||||
handler.setLevel(logging.DEBUG) |
||||
logger.setLevel(logging.DEBUG) |
||||
|
||||
try: |
||||
logger.info('Parsing headers: %s', header) |
||||
headers = parse_colon_delimited_options(header) |
||||
except ValueError: |
||||
logging.exception('Could not parse the parameters with "--header": %s', |
||||
header) |
||||
return EXIT_CODE_INVALID_REQUEST_VALUES |
||||
|
||||
try: |
||||
request = NetworkRequest(url, POST, headers, body, float(timeout)) |
||||
except ValueError: |
||||
logger.exception('Invalid request values passed into the script.') |
||||
return EXIT_CODE_INVALID_REQUEST_VALUES |
||||
|
||||
status = make_request(request) |
||||
|
||||
# View exit code after running to get the http status code: 'echo $?' |
||||
return status |
||||
|
||||
|
||||
def get_argsparser(): |
||||
"""Returns the argument parser. |
||||
|
||||
Returns: |
||||
Argument parser for the script. |
||||
""" |
||||
|
||||
parser = argparse.ArgumentParser( |
||||
description='The script takes in the arguments of a network request. ' |
||||
'The network request is sent and the http status code will be' |
||||
'returned as the exit code.') |
||||
subparsers = parser.add_subparsers(help='Commands:') |
||||
post_parser = subparsers.add_parser( |
||||
post.__name__, help='{} help'.format(post.__name__)) |
||||
post_parser.add_argument( |
||||
'--url', |
||||
help='Request url. Ex: https://www.google.com/somePath/', |
||||
required=True, |
||||
dest='url') |
||||
post_parser.add_argument( |
||||
'--header', |
||||
help='Request headers as a space delimited list of key ' |
||||
'value pairs. Ex: "key1:value1 key2:value2"', |
||||
action='append', |
||||
required=False, |
||||
dest='header') |
||||
post_parser.add_argument( |
||||
'--body', |
||||
help='The body of the network request', |
||||
required=True, |
||||
dest='body') |
||||
post_parser.add_argument( |
||||
'--timeout', |
||||
help='The timeout in seconds', |
||||
default=10.0, |
||||
required=False, |
||||
dest='timeout') |
||||
post_parser.add_argument( |
||||
'--verbose', |
||||
help='Should verbose logging be outputted', |
||||
action='store_true', |
||||
default=False, |
||||
required=False, |
||||
dest='verbose') |
||||
post_parser.set_defaults(func=post) |
||||
return parser |
||||
|
||||
|
||||
def map_http_status_to_exit_code(status_code): |
||||
"""Map an http status code to the appropriate exit code. |
||||
|
||||
Exit codes in python are valid from 0-256, so we want to map these to |
||||
predictable exit codes within range. |
||||
|
||||
Args: |
||||
status_code: the input status code that was output from the network call |
||||
function |
||||
|
||||
Returns: |
||||
One of our valid exit codes declared at the top of the file or a generic |
||||
unknown error code |
||||
""" |
||||
if status_code <= MAX_EXIT_CODE: |
||||
return status_code |
||||
|
||||
if status_code > 199 and status_code < 300: |
||||
return EXIT_CODE_SUCCESS |
||||
|
||||
if status_code == 302: |
||||
return EXIT_CODE_HTTP_REDIRECT_ERROR |
||||
|
||||
if status_code == 404: |
||||
return EXIT_CODE_HTTP_NOT_FOUND_ERROR |
||||
|
||||
if status_code > 499: |
||||
return EXIT_CODE_HTTP_SERVER_ERROR |
||||
|
||||
return EXIT_CODE_HTTP_UNKNOWN_ERROR |
||||
|
||||
|
||||
def main(): |
||||
"""Main function to run the program. |
||||
|
||||
Parse system arguments and delegate to the appropriate function. |
||||
|
||||
Returns: |
||||
A status code - either an http status code or a custom error code |
||||
""" |
||||
parser = get_argsparser() |
||||
subparser_action = parser.parse_args() |
||||
try: |
||||
return subparser_action.func(subparser_action) |
||||
except ValueError: |
||||
logger.exception('Invalid arguments passed.') |
||||
parser.print_help(sys.stderr) |
||||
return EXIT_CODE_INVALID_REQUEST_VALUES |
||||
return EXIT_CODE_GENERIC_HTTPLIB_ERROR |
||||
|
||||
if __name__ == '__main__': |
||||
exit_code = map_http_status_to_exit_code(main()) |
||||
sys.exit(exit_code) |
@ -1,11 +0,0 @@ |
||||
fileFormatVersion: 2 |
||||
guid: e6e32fecbfd44fab946fa160e4861924 |
||||
labels: |
||||
- gvh |
||||
- gvh_version-10.3.0 |
||||
- gvhp_exportpath-Firebase/Editor/network_request.py |
||||
timeCreated: 1480838400 |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
Loading…
Reference in new issue