Skip to content

Instantly share code, notes, and snippets.

@RameshRavone
Created November 8, 2021 10:53
Show Gist options
  • Select an option

  • Save RameshRavone/5b00e9d098e1f7bf034aed4cafac8c80 to your computer and use it in GitHub Desktop.

Select an option

Save RameshRavone/5b00e9d098e1f7bf034aed4cafac8c80 to your computer and use it in GitHub Desktop.
GDFirebase Installer
import os
import sys
import shutil
import urllib3
import xml.etree.ElementTree as ET
import zipfile
from os import path
from xml.dom import minidom
import requests
RED = "\033[1;31m"
BLUE = "\033[1;34m"
CYAN = "\033[1;36m"
GREEN = "\033[0;32m"
RESET = "\033[0;0m"
BOLD = "\033[;1m"
REVERSE = "\033[;7m"
UNDERLINE = '\033[4m'
manifest_meta = {
"admob": {
"com.google.android.gms.ads.APPLICATION_ID":
"""<meta-data android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="@string/admob_app_id"/>"""
},
"play_service": {
"com.google.android.gms.games.APP_ID":
"""<meta-data android:name="com.google.android.gms.games.APP_ID"
android:value="@string/play_service_app_id" />""",
"com.google.android.gms.version":
"""<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>"""
},
"facebook": {
"com.facebook.sdk.ApplicationId":
"""<meta-data android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id"/>"""
}
}
manifest_activity = {
"facebook": {
"com.facebook.FacebookActivity":
"""<activity android:name="com.facebook.FacebookActivity"
android:configChanges=
"keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="@string/godot_project_name_string" />""",
"com.facebook.CustomTabActivity":
"""<activity android:name="com.facebook.CustomTabActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="@string/fb_login_protocol_scheme" />
</intent-filter>
</activity>"""
}
}
remote = ""
api_link = "https://api.github.com/repos/Frogsquare/GDFirebase/releases/latest"
block_sz = 8192
ids_tree = None
tmpdir = ""
cached_dir = ""
project_root = ""
android_build_dir = ""
android_plugin_dir = ""
android_plugin_libdir = ""
android_ids_xml = ""
manifest_lines = []
plugins = {
"Admob": True,
"Auth": True,
"CloudMessaging": True,
"Config": True,
"Storage": True,
"Firestore": True,
}
options = {"admob": {}, "auth": {}}
ids = {
"admob_app_id": "", # Admob
"play_service_app_id": "", # Play Service
"facebook_app_id": "", # Facebook
"fb_login_protocol_scheme": ""
}
def updateManifest():
# Make AndroidManifes.xml.backup
manifest = path.join(android_build_dir, "AndroidManifest.xml")
if path.exists(manifest) == False:
print(RED+"AndroidManifest.xml"+RESET+" File not Found in " + android_build_dir)
quit()
if not path.exists(manifest + ".backup"):
print("Make a backup of current AndroidManifest.xml file")
shutil.copyfile(manifest, manifest+".backup")
with open(manifest, 'r') as file:
manifest_lines = file.readlines()
insert_index = -1
for idx, line in enumerate(manifest_lines):
if "</application>" in line:
insert_index = idx + 1
manifest_lines[idx] = line.replace("</application>", "")
manifest_lines.insert(insert_index, "\n\n")
manifest_lines.insert(insert_index+1, "\t</application>\n")
break
meta_found = []
activitys_found = []
app = ET.parse(manifest).getroot().find("application")
if not app is None:
for element in app.findall("meta-data"):
meta_found.append(element.get("{http://schemas.android.com/apk/res/android}name"))
for element in app.findall("activity"):
activitys_found.append(element.get("{http://schemas.android.com/apk/res/android}name"))
newLines = ["\t"]
if plugins["Admob"] == True:
for name in manifest_meta["admob"].keys():
if not name in meta_found:
newLines.append(manifest_meta["admob"][name])
newLines.append("\n")
if plugins["Auth"] == True:
for name in manifest_meta["facebook"].keys():
if not name in meta_found:
newLines.append(manifest_meta["facebook"][name])
newLines.append("\n")
for name in manifest_activity["facebook"].keys():
if not name in activitys_found:
newLines.append(manifest_activity["facebook"][name])
newLines.append("\n")
if len(newLines) > 1:
line = "\n\t".join(newLines)
manifest_lines.insert(insert_index, line)
with open(manifest, 'w') as file:
print("writting " + "".join(manifest_lines))
file.writelines(manifest_lines)
pass
def validProjectRoot(dirpath):
exists = path.exists(dirpath) and path.isdir(dirpath)
return exists and path.exists(path.join(dirpath, "project.godot"))
def prepare():
global cached_dir
global tmpdir
global android_plugin_dir
global android_plugin_libdir
global android_ids_xml
cached_dir = path.join(project_root, ".fsqr")
if not path.exists(cached_dir) or not path.isdir(cached_dir):
os.makedirs(cached_dir)
tmpdir = path.join(cached_dir, "tmp")
if not path.exists(tmpdir) or not path.isdir(tmpdir):
os.makedirs(tmpdir)
android_plugin_dir = path.join(project_root, "android/plugins")
if not path.exists(android_plugin_dir) or not path.isdir(android_plugin_dir):
os.makedirs(android_plugin_dir)
android_plugin_libdir = path.join(android_plugin_dir, "libs")
if not path.exists(android_plugin_libdir) or not path.isdir(android_plugin_libdir):
os.makedirs(android_plugin_libdir)
android_ids_xml = path.join(android_build_dir, "res/values/ids.xml")
if path.exists(android_ids_xml):
try:
global ids_tree
ids_tree = ET.parse(android_ids_xml)
root = ids_tree.getroot()
for element in root.findall("string"):
elementName = element.get("name")
if elementName:
ids[elementName] = element.text or ""
except ET.ParseError: print("Parsing "+android_ids_xml+" File")
else:
with open(android_ids_xml, 'w') as _: pass
pass
def getApiKey(name, currentVal = ""):
val = ""
while val == "":
val = input(CYAN+name+RESET+" Application Id ("+currentVal+"): ")
if val is None or val == "":
val = currentVal
else:
confirm = input("Confirm `"+UNDERLINE+val+RESET+"` (Y/n): ")
if confirm and confirm.lower()[0] == "n": val = ""
return val
def quit():
print("Quitting GDFirebase setup.!")
exit(0)
def main():
args = sys.argv[1:]
if len(args) != 1:
print("Error Call: python3 gdfirebase.py [GODOT-PROJECT-DIR]")
quit()
if not validProjectRoot(args[0]):
print("Not a valid `Godot` project root directory")
quit()
global project_root
global android_build_dir
project_root = path.abspath(args[0])
android_build_dir = path.join(project_root, "android/build")
if not path.exists(android_build_dir) or not path.isdir(android_build_dir):
print("`android/build` directory does not exists, Install Android Template from `project menu`.")
quit()
prepare() # Creating cache directorys and loading ids.xml file
for key in plugins.keys():
val = input(BLUE+"Include " + RESET + key + " (Y/n): ")
if val and val.lower()[0] == "n": plugins[key] = False
else: plugins[key] = True
# If using AdMob get AppId
if plugins["Admob"] == True:
currentVal = ids["admob_app_id"]
val = getApiKey("AdMob", currentVal)
ids["admob_app_id"] = val
# If using Auth get FacebookAppId
if plugins["Auth"] == True:
currentVal = ids["facebook_app_id"]
val = getApiKey("Facebook", currentVal)
ids["facebook_app_id"] = val
ids["fb_login_protocol_scheme"] = "fb" + val
confiremed = input("Continue (y/N): ")
if confiremed is None or confiremed.lower()[0] == "n": quit()
else:
if ids_tree is None:
root = ET.Element("resources")
root.text = "\n"
for id in ids:
val = ids[id]
if val != "":
e = ET.SubElement(root, "string", name=id)
e.text = ids[id]
e.tail = "\n"
minidom.parseString(ET.tostring(root)).toprettyxml(indent=" ")
tree = ET.ElementTree(root)
tree.write(android_ids_xml, encoding="utf-8", xml_declaration=True)
else:
ids_tree.write(android_ids_xml, encoding="utf-8", xml_declaration=True)
updateManifest()
getLatestRelease()
assert remote != ""
# Download the plugins
file_name = remote.split('/')[-1]
dest = path.join(cached_dir, file_name)
if not path.exists(dest):
downloadPlugin(file_name, dest)
else:
print("Reusing the downloaded release from, " + cached_dir)
with zipfile.ZipFile(dest, 'r') as zip:
zip.extractall(tmpdir)
added = []
for key in plugins.keys():
if plugins[key] == True:
plugin = "GDFirebase"+key
gdap = path.join(tmpdir, plugin+".gdap")
lib = path.join(path.join(tmpdir, "libs"), plugin+".aar")
if path.exists(gdap) and path.exists(lib):
added.append(key)
shutil.copy(gdap, android_plugin_dir)
shutil.copy(lib, android_plugin_libdir)
pass
if path.exists(tmpdir):
shutil.rmtree(tmpdir)
print("")
print(BLUE+"Installed"+RESET+" "+ str(added))
print("If you find any problems are need improvements open an issue at `https://github.com/FrogSquare/GDFirebase/issues`")
pass
def getLatestRelease():
try:
r = requests.get(api_link)
assets = r.json()["assets"]
if len(assets) <= 0:
print("Release has no assets to download")
quit()
global remote
for asset in assets:
url = str(asset["browser_download_url"])
if url.endswith(".zip"):
remote = url
break
except Exception:
print("GDFirebase Download Failed.")
quit()
def downloadPlugin(file_name, dest):
http = urllib3.PoolManager()
u = http.request('GET', remote, preload_content=False)
meta = u.info()
file_size = int(meta.getheaders("Content-Length")[0])
info_fmt = GREEN+"Downloading:"+RESET+" %s "+GREEN+"Size:"+RESET+" %.1f KB"
status_fmt = r"%10d [%3.2f%%]"
print (info_fmt % (file_name, file_size / 1024.0))
file_size_dl = 0
with open(dest, "wb") as out:
while True:
buffer = u.read(block_sz)
if not buffer:
print(status_fmt % (file_size_dl, file_size_dl * 100. / file_size))
break
file_size_dl += len(buffer)
out.write(buffer)
status = status_fmt % (file_size_dl, file_size_dl * 100. / file_size)
print (status + chr(8) * (len(status) + 1), end="\r")
pass
if __name__ == "__main__":
main()
@RameshRavone
Copy link
Author

python3 gdfirebase.py [GAME-PROJECT-DIR]

Not a beautiful one, But work's. It has been years since I used python

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment