152 lines
5.3 KiB
Python
152 lines
5.3 KiB
Python
#!/usr/bin/python3
|
|
|
|
# THIS SOFTWARE IS A PART OF FREE COMPETITOR PROJECT
|
|
# THE FOLLOWING SOURCE CODE I UNDER THE GNU
|
|
# AGPL LICENSE V3 OR ANY LATER VERSION.
|
|
|
|
# This project is not for simple users, but for
|
|
# web-masters and a like, so we are counting on
|
|
# your ability to set it up and running.
|
|
|
|
# Server side
|
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
|
from subprocess import *
|
|
import json
|
|
import os
|
|
|
|
from modules import search
|
|
from modules import render
|
|
|
|
# Author: https://www.delftstack.com/howto/python/python-print-colored-text/
|
|
class bcolors:
|
|
OK = '\033[92m' #GREEN
|
|
WARNING = '\033[93m' #YELLOW
|
|
FAIL = '\033[91m' #RED
|
|
RESET = '\033[0m' #RESET COLOR
|
|
|
|
print("""╔═╗┬─┐┌─┐┌─┐╔═╗┌─┐┌┬┐┌─┐┌─┐┌┬┐┬┌┬┐┌─┐┬─┐┌─┐
|
|
╠╣ ├┬┘├┤ ├┤ ║ │ ││││├─┘├┤ │ │ │ │ │├┬┘└─┐
|
|
╚ ┴└─└─┘└─┘╚═╝└─┘┴ ┴┴ └─┘ ┴ ┴ ┴ └─┘┴└─└─┘
|
|
|
|
Copyright (C) 2022 Jeison Yehuda Amihud and contributors.
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Affero General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
""")
|
|
|
|
print("Loading config...")
|
|
if os.path.exists("config.json"):
|
|
with open("config.json","r") as f:
|
|
srvConfig = json.load(f)
|
|
ADDRESS = srvConfig["address"]
|
|
PORT = srvConfig["port"]
|
|
CSS = srvConfig["css"]
|
|
print(bcolors.OK + "Loaded Configuration: " + bcolors.RESET)
|
|
print("Address: "+ ADDRESS)
|
|
print("Port: "+ str(PORT)) # Do not think people are smart at syntax
|
|
print("CSS: "+ CSS)
|
|
try:
|
|
PORT = int(PORT)
|
|
except:
|
|
print(bcolors.FAIL + "ERR: Port should be a number" + bcolors.RESET)
|
|
exit()
|
|
else:
|
|
newConfig = open("config.json", "w")
|
|
newConfig.write("""{
|
|
"INFO" : "You would be better off setting address to the full URL of the FreeCompetitors instance.",
|
|
"address" : "/",
|
|
"port" : 8080,
|
|
"css" : "https://zortazert.codeberg.page/style/safety.css"
|
|
}""")
|
|
newConfig.close
|
|
print(bcolors.WARNING + "Please edit the configuration file \"config.json\"." + bcolors.RESET)
|
|
exit()
|
|
|
|
# Who fucking made this http.server so I need to use classes?
|
|
# I fucking hate who ever thought that it was a good idea...
|
|
class handler(BaseHTTPRequestHandler):
|
|
|
|
def start_page(self):
|
|
self.send_response(200)
|
|
if "/json/" not in self.path:
|
|
self.send_header('Content-type', 'text/html')
|
|
else:
|
|
self.send_header('Content-type', 'application/json')
|
|
self.end_headers()
|
|
|
|
def send(self, text):
|
|
text = str(text)
|
|
csstext = '<link media="all" href="'+CSS+'" type="text/css" rel="stylesheet" />'
|
|
text = '<head>'+csstext+'</head><body>'+text+'</body>'
|
|
|
|
|
|
|
|
self.start_page()
|
|
self.wfile.write(text.encode("utf-8"))
|
|
|
|
def do_GET(self):
|
|
|
|
if self.path.startswith("/json/"):
|
|
|
|
# API CALL
|
|
|
|
|
|
term = self.path[6:]
|
|
software_data, match = search.search_app(term)
|
|
data = {"found":{"data":software_data,"match":match}}
|
|
data["suggestions"] = search.suggest(software_data)
|
|
text = json.dumps(data, indent = 2)
|
|
|
|
self.start_page()
|
|
self.wfile.write(text.encode("utf-8"))
|
|
|
|
|
|
elif self.path == "/":
|
|
|
|
# If the user is at the front page, let him get only the search bar
|
|
|
|
page = "<center><br><br><br><h1>Free Competitors</h1>"
|
|
page = render.search_widget(page, ADDRESS)
|
|
page = page + "<p>Please search for any software to which you would like to find a Free Software replacement.</p></center>"
|
|
page = render.source_code_link(page)
|
|
self.send(page)
|
|
|
|
elif "/search?item=" in self.path:
|
|
|
|
# Clearing the url
|
|
# instead of it being /search?item=softwarename
|
|
# it will be just /softwarename
|
|
|
|
item = self.path[self.path.find("item=")+5:].lower()
|
|
self.send('<meta http-equiv="Refresh" content="0; url=\'/'+item+'\'" />')
|
|
|
|
else:
|
|
|
|
# This is when the fun is
|
|
|
|
software = self.path.replace("/", "").replace("+", " ")
|
|
|
|
software_data, match = search.search_app(software)
|
|
|
|
page = render.search_widget("", ADDRESS)
|
|
page = page +"Search match: "+ str(int(match*100))+"%"
|
|
# Let's add the found software to the page
|
|
page = render.html(page, software_data)
|
|
page = render.suggestions(page, software_data)
|
|
page = render.source_code_link(page)
|
|
|
|
self.send(page)
|
|
|
|
serve = HTTPServer(("", PORT), handler)
|
|
print(bcolors.OK + "⚡Now serving on port "+ str(PORT) +" at "+ ADDRESS +"." + bcolors.RESET)
|
|
serve.serve_forever()
|