-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinit.py
153 lines (117 loc) · 5.92 KB
/
init.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import os
import sys
import platform
import subprocess
import json
import glob
from pathlib import Path
sPlatform = platform.system().lower()
lInstalledPackages = []
sCliPrefix = "[ecosia-postloader] "
sConfPath = "./config/settings.json"
def unloadApp(sWatchFilePath):
"""
Removes the injected file on user confirmation
"""
print(sCliPrefix + "The app has already been configured and is watching.")
sIn = input(sCliPrefix + "Do you want to unload it? [y/n]")
if sIn.lower() in ["yes", "y"]:
if sPlatform == "darwin":
subprocess.run(["launchctl", "unload", sWatchFilePath])
os.unlink(sWatchFilePath)
print(sCliPrefix + "Successfully unloaded.")
def initEnv():
"""
For MacOS an AppleScript starting the Node.js sever is called directly on trigger launch, event-driven by sytem events
---
For Windows the Node.js server is started on os startup and will listen for trigger launch to start the WebSocket server afterwards
"""
# Clone and inject the file for watching the trigger launch
if sPlatform == "darwin":
sProjWatchFilePath = "./host/trigger/darwin/sysevt.plist"
sSysInjectPath = os.path.expanduser("~/Library/LaunchAgents/com.floriangoetzrath.ecosia-postloader.plist")
elif sPlatform == "windows":
sProjWatchFilePath = "./host/trigger/win/startup.bat"
sSysInjectPath = os.getenv("APPDATA") + "/Microsoft/Windows/Start Menu/Programs/Startup/ecosia-postloader.bat"
# If the watcher is already injected, prompt the user and terminate
lExistingSysFilePath = glob.glob(sSysInjectPath.split(".")[0] + ".*")
if lExistingSysFilePath:
unloadApp(lExistingSysFilePath[0])
exit()
# Create the watcher
with open(sSysInjectPath, "w") as sysFile:
with open(sProjWatchFilePath, "r") as projFile:
with open(sConfPath, "r") as confFile:
jsonConfContent = json.loads(confFile.read())
sContent = projFile.read()
sContent = sContent.replace("project_path", jsonConfContent["project_path"])
sContent = sContent.replace("trigger_process_name", jsonConfContent["trigger_process_name"])
sysFile.write(sContent)
# Register the new system event
if sPlatform == "darwin":
subprocess.run(["launchctl", "load", sSysInjectPath])
# Create the .exe for sys startup
if sPlatform == "windows" and "pyinstaller" in lInstalledPackages:
import PyInstaller.__main__
sProjWatchFilePath = os.path.join(os.path.abspath(sProjWatchFilePath.replace("bat", "py")))
sProjWatchPath = sProjWatchFilePath.replace("startup.py", "")
with open(sProjWatchFilePath, "r") as projPyFile:
with open(sProjWatchPath + "/startup_tmp.py", "w") as projTmpPyFile:
with open(sConfPath, "r") as confFile:
jsonConfContent = json.loads(confFile.read())
sProjFileContent = projPyFile.read()
sProjFileContent = sProjFileContent.replace("project_path", jsonConfContent["project_path"])
projTmpPyFile.write(sProjFileContent)
PyInstaller.__main__.run([
sProjWatchPath + "/startup_tmp.py",
"--onefile",
"--nowindow",
"--distpath=" + sProjWatchPath + "/dist",
"--workpath=" + sProjWatchPath + "/build",
"--specpath=" + sProjWatchPath
])
with open(sSysInjectPath.replace(".bat", ".exe"), "bx") as sysFile:
with open(sProjWatchPath + "/dist/startup_tmp.exe", "br") as projFile:
sysFile.write(projFile.read())
# Delete redundant tmp and batch file
os.unlink(sProjWatchPath + "/startup_tmp.py")
os.unlink(sSysInjectPath)
print(sCliPrefix + "Successfully loaded.")
def buildConfig():
"""
Launches a shell dialog and builds the config
"""
sConfTriggerName = "Brave Browser"
sConfPlatform = sPlatform
sConfProjectPath = str(Path().absolute()).replace("\\", "/")
sConfAmntAdsToClick = "1"
print(sCliPrefix + "Seems like there is no valid config file. Proceeding to build one...")
sConfTriggerName = input(sCliPrefix + "Enter the name of the process used as a trigger to start the background services: (" + sConfTriggerName + ") ") or sConfTriggerName
sConfPlatform = input(sCliPrefix + "Enter your platform: (" + sPlatform + ") ").lower() or sConfPlatform
sConfProjectPath = input(sCliPrefix + "Enter the path to the project: (" + sConfProjectPath + ") ") or sConfProjectPath
sConfAmntAdsToClick = input(sCliPrefix + "Enter the number of ads to click from the Ecosia served page: (" + sConfAmntAdsToClick + ") ") or sConfAmntAdsToClick
sConfVals = json.dumps({
'trigger_process_name': sConfTriggerName,
'platform': sConfPlatform,
'project_path': sConfProjectPath,
'amnt_ads_to_click': int(sConfAmntAdsToClick)
}, indent=4, sort_keys=True)
with open(sConfPath, "w") as file:
file.write(sConfVals)
if __name__ == '__main__':
"""
ecosia-postloader > init.py
"""
if not Path("./config/settings.json").exists():
buildConfig()
# If on Windows offer to create a .exe startup file to bypass the command line window
if sPlatform == "windows":
res = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'])
lInstalledPackages = [r.decode().split('==')[0] for r in res.split()]
if not "pyinstaller" in lInstalledPackages:
print(sCliPrefix + "The following package is not installed on your system: pyinstaller")
print(sCliPrefix + "If installed there will be no command prompt associated with this application when you power on your machine.")
sIn = input(sCliPrefix + "Would you like to install it? [y/n]")
if sIn.lower() in ["yes", "y"]:
subprocess.run(["pip", "install", "pyinstaller"])
initEnv()