diff --git a/modules/render.py b/modules/render.py
new file mode 100644
index 0000000..cf020d0
--- /dev/null
+++ b/modules/render.py
@@ -0,0 +1,84 @@
+# 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.
+
+from modules import search
+
+def html(page, json):
+
+ # This function adds a rendering of the json into the page
+
+ free = False
+ if "licenses" in json and json["licenses"]:
+ free = True
+
+ page = page + "\n
"
+ try:
+ page = page + '\n'
+ except:
+ pass
+
+ # Name / Website link
+ name = json.get("names",["Unknown"])[0]
+
+
+ page = page + "\n" + name
+
+ page = page + "
"
+
+ # Few words about it
+ page = page + ""+json.get("comment","")+"
"
+
+ # Links
+ website = json.get("links",{}).get("website", "")
+ if free and website:
+ page = page + """
+
+ """
+
+ git = json.get("links",{}).get("git", "")
+ if git:
+ page = page + """
+
+ """
+
+ wikipedia = json.get("links",{}).get("wikipedia", "")
+ if wikipedia:
+ page = page + """
+
+ """
+
+
+ return page
+
+def suggestions(page, json):
+
+ # This function will render suggestions
+
+ page = page + "
Replacements:
"
+
+ found = search.suggest(json)
+
+ for i in found:
+
+ free = False
+ if "licenses" in i[-1] and i[-1]["licenses"]:
+ free = True
+
+ print(i[-1].get("names", ["nothing"])[0])
+ if not i[0] or i[-1] == json or not free:
+ continue
+ page = page + "
"
+ page = html(page, i[-1])
+
+ return page
diff --git a/modules/search.py b/modules/search.py
new file mode 100644
index 0000000..76fedf5
--- /dev/null
+++ b/modules/search.py
@@ -0,0 +1,92 @@
+# 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
+import json
+import Levenshtein
+
+
+def search_app(name):
+
+ # This function output a json of an app that's the closest
+ # match to the requested name.
+
+ closest = {}
+ match = 0
+
+ all_apps = []
+ for i in os.listdir("apps"):
+ if i.endswith(".json"):
+
+ try:
+ with open("apps/"+i) as json_file:
+ idata = json.load(json_file)
+ except Exception as e:
+ print("Error!", e)
+ idata = {}
+
+ all_apps.append(idata)
+ # Round 1. By the name
+
+ for i in all_apps:
+ for n in i.get("names",[]):
+ m = Levenshtein.jaro_winkler(n.lower(), name.lower())
+ if m > match and m > 0.49:
+ closest = i
+ match = m
+
+ if closest:
+ return closest
+
+ # Round 2. By Generic name
+
+ for i in all_apps:
+ for n in i.get("generic_name",[]):
+ m = Levenshtein.jaro_winkler(n.lower(), name.lower())
+ if m > match:
+ closest = i
+ match = m
+
+ if closest:
+ return closest
+
+def suggest(json_data):
+
+ # This function will suggest
+
+
+ found = []
+ all_apps = []
+ for i in os.listdir("apps"):
+ if i.endswith(".json"):
+
+ try:
+ with open("apps/"+i) as json_file:
+ idata = json.load(json_file)
+ except Exception as e:
+ print("Error!", e)
+ idata = {}
+
+ all_apps.append(idata)
+
+ for i in all_apps:
+ score = 0
+ for c in ["generic_name", "networks_read", "networks_write", "formats_read", "formats_write"]:
+
+ for b in json_data.get(c, []):
+ if b in i.get(c, []):
+ score += 1
+ print(score, "SCORE")
+ found.append([score, i])
+
+ try:
+ found = reversed(sorted(found))
+ except:
+ return []
+
+ return found