diff --git a/data/favicon_requests.json b/data/favicon_requests.json new file mode 100644 index 0000000..31b62eb --- /dev/null +++ b/data/favicon_requests.json @@ -0,0 +1,20 @@ +[ + 1650038528.6090891, + 1650038640.6455874, + 1650038641.8818197, + 1650038643.079802, + 1650038644.242559, + 1650038645.3251307, + 1650038646.4718275, + 1650038647.479486, + 1650038648.4314067, + 1650038649.4624548, + 1650038650.494474, + 1650043243.9023528, + 1650043460.1411445, + 1650043460.315897, + 1650043490.4135377, + 1650043958.2914546, + 1650043959.0416543, + 1650044037.8992538 +] \ No newline at end of file diff --git a/favicon.png b/favicon.png new file mode 100644 index 0000000..fc065a3 Binary files /dev/null and b/favicon.png differ diff --git a/modules/#render.py# b/modules/#render.py# new file mode 100644 index 0000000..aa08c08 --- /dev/null +++ b/modules/#render.py# @@ -0,0 +1,360 @@ +# 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. + +import os +from modules import search + + +def html(page, json): + + # This function adds a rendering of the json into the page + + free = search.is_free(json) + name = json.get("names",["Unknown"])[0] + page = page + """ + + + + + """ + page = page + "\n " + page = page + "\n

" + try: + page = page + '\n [LOGO] \n' + except: + pass + + page = page + " "+ name +" \n" + page = page + "

\n
\n\n" + + page = page + """ + + + + """ + + # Few words about it + comment = json.get("comment","") + not_foss = ['open source', 'open-source'] + if "open source" or "open-source" in comment.lower(): + # Well... Here is a thing. Free Software, not open source. + where = comment.lower().find("open source") + # In case it has a slash in it. + if where == -1: + where = comment.lower().find("open-source") + ops = comment[where:where+11] + if ops: + comment = comment.replace(ops, + ""+ops+"") + page = page + "\n

\n "+comment+"\n

\n\n" + + # I want to show nothing else from if it's proprietary + issues_files = list(os.listdir("data/issues")) + if "issues" in json: + l = json.get("issues", []) + page = page +"

Anti-Features / Problems:

" + + for i in l: + if i+".html" not in issues_files: + page = page + "  "+i+"
" + else: + page = page + '
' + page = page + "  "+i+"" + issuefile = open("data/issues/"+i+".html") + page = page + "

"+issuefile.read()+"

" + page = page + "
" + if not free: + return page + + + # Links + + page = page + """ + + + """ + + page = page + """ + + + + + """ + + page = page + "" + linksfilter = {"git":"source"} + links = json.get("links", {}) + for website in links: + if website in ["icon"]: + continue + link = links[website] + page = page + """ + + + + + """ + + page = page + "
+
+ +
+
" + + page = page + """ + + + + """ + + # Details + + categories = {"generic_name":"Features", + "licenses":"License(s)", + "platforms":"Platforms", + "networks_read":"Accesses Data from", + "networks_write":"Interacts / Publishes to", + "formats_read":"Opens from File-Formats", + "formats_write":"Saves to File-Formats", + "interface":"Interface", + "languages":"Programming Languages"} + + for c in categories: + + l = json.get(c, []) + if not l: + continue + + # I want to look whether this category has a list of files + alldata = list(os.listdir("data")) + allfiles = [] + for folder in alldata: + if c.startswith(folder): + try: + allfiles = list(os.listdir("data/"+folder)) + break + except: + pass + # Count matches + matches = 0 + for i in l: + if i.startswith("*"): + matches += 1 + if matches: + matchtext = "( "+str(matches)+" )" + else: + matchtext = "" + page = page + "\n\n
" + page = page +"\n "+categories[c]+": "+matchtext+"" + + for i in l: + matchtext = "" + if i.startswith("*"): + i = i[1:] + matchtext = "    ( match ) " + if i+".html" in allfiles: + datapage = open("data/"+folder+"/"+i+".html") + page = page + """ + + + + """ + page = page + "
\n" + page = page + "     "+matchtext+i+"\n" + page = page + " \n

\n" + page = page + " " + datapage.read()+"\n" + page = page + "

\n
\n
" + else: + page = page + "\n     "+matchtext+i+"\n
\n" + page = page + """ + + +
+ +
+ + """ + + + return page + +def suggestions(page, json): + + # This function will render suggestions + + page = page + """ + + + +

Free Competitors:

+ + """ + + found = search.suggest(json) + + biggest = 0 + for i in found: + if i[0] > biggest: + biggest = i[0] + more = False + for i in found: + free = search.is_free(i[-1]) + + if not i[0] or i[-1]["names"] == json["names"] or not free: + continue + try: + frac = int(i[0]/biggest*100) + except: + frac = 0 + + if frac < 20 and not more: # Below 40% features match + page = page + """ + + + +
+
+

Problematic Competitors:

+ + """ + more = True + + page = page +""" + +
+ + + """ + + page = page + "
Suggestion score: " + str(frac) + "%" + page = html(page, i[-1]) + + if more: + page = page + "
" + return page + +def search_widget(page, address): + + # Adds a search bar to the page + + page = page + """ + + +
+ + +
+ + + + """ + #page = page.format(ADDRESS) + + return page + +def source_code_link(page): + + # Adds a source code link + + page = page + """ + + + +
+
+ +
+ +

This website is under the GNU AGPL license.

+ + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ + + + + """ + + + + return page diff --git a/modules/.#render.py b/modules/.#render.py new file mode 120000 index 0000000..95a612e --- /dev/null +++ b/modules/.#render.py @@ -0,0 +1 @@ +vcs@vcs-Lenovo-IdeaPad-S145-15IWL.3286:1650042546 \ No newline at end of file diff --git a/server.py b/server.py index 5baa7af..3a3ee83 100644 --- a/server.py +++ b/server.py @@ -13,6 +13,7 @@ from http.server import BaseHTTPRequestHandler, HTTPServer from subprocess import * import json import os +import time from modules import search from modules import render @@ -84,16 +85,21 @@ class handler(BaseHTTPRequestHandler): self.send_header('Content-type', 'text/css') elif self.path == "/ttf": self.send_header('Content-type', 'font/ttf') + elif self.path in ["/favicon.png", "/logo"]: + self.send_header('Content-type', 'image/png') else: self.send_header('Content-type', 'text/html') self.end_headers() def send(self, textin): + textin = str(textin) csstext = '' text = " \n\n" text = text + "\n" text = text + ''+csstext+'\n\n' + text = text + "\n\n" + text = text + '' text = text + "\n" text = text + '\n\n'+textin+'\n\n' @@ -117,13 +123,19 @@ class handler(BaseHTTPRequestHandler): 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 = "



Free Competitors

" + page = """
+


+ + [LOGO] +

Free Competitors

""" page = render.search_widget(page, ADDRESS) page = page + "

Please search for any software to which you would like to find a Free Software replacement.

" page = render.source_code_link(page) @@ -155,7 +167,33 @@ class handler(BaseHTTPRequestHandler): faqfile = render.source_code_link(faqfile) self.send(faqfile) + elif "/favicon.png" == self.path: + + # I'm recording all the favicons request times to get + # a rough estimate of how many people visit when. + # It seems like the browser is visiting the site for + # the first time ( at least in a given session ) it + # asks for a 'favicon.ico'. So I store each of those + # requests time. As a timestamp. + try: + with open("data/favicon_requests.json") as json_file: + favicons = json.load(json_file) + except: + favicons = [] + favicons.append(time.time()) + with open("data/favicon_requests.json", 'w') as f: + json.dump(favicons, f, indent=4, sort_keys=True) + + icon = open("favicon.png", "rb") + icon = icon.read() + self.wfile.write(icon) + + elif "/logo" == self.path: + + icon = open("favicon.png", "rb") + icon = icon.read() + self.wfile.write(icon) elif "/search?item=" in self.path: