|
@@ -0,0 +1,163 @@
|
|
|
|
+# 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.
|
|
|
|
+
|
|
|
|
+##################################################
|
|
|
|
+
|
|
|
|
+# This file is importart, since it's important to
|
|
|
|
+# keep track of software that the users are
|
|
|
|
+# searching, but not getting any answers to.
|
|
|
|
+# The idea is very simple. If the score of any
|
|
|
|
+# search is below 60%, we add the search term into
|
|
|
|
+# a list. But instead of it being a dumb list, it's
|
|
|
|
+# a smart list.
|
|
|
|
+
|
|
|
|
+# Using the similar() function we can group very
|
|
|
|
+# similar terms together. So the users could misspel
|
|
|
|
+# certain names. For example we might group '3D Max'
|
|
|
|
+# '3DSMax' into the same data-structure. Using the
|
|
|
|
+# simple count of how much users spell this or that
|
|
|
|
+# name more often, we will make a suggestion for the
|
|
|
|
+# maintainer. So the maintainer could add the missing
|
|
|
|
+# names into the data. Or at least report them to us.
|
|
|
|
+
|
|
|
|
+##################################################
|
|
|
|
+
|
|
|
|
+import os
|
|
|
|
+import json
|
|
|
|
+
|
|
|
|
+from difflib import SequenceMatcher # checks how similar are two strings
|
|
|
|
+
|
|
|
|
+def similar(a, b):
|
|
|
|
+ # I guess it simpifies the syntax for SequenceMatcher
|
|
|
|
+ # In the previous version we use Lavenshtain but it made
|
|
|
|
+ # it an issue for some people to install.
|
|
|
|
+ return SequenceMatcher(None, a, b).ratio()
|
|
|
|
+
|
|
|
|
+def add(name):
|
|
|
|
+
|
|
|
|
+ # This function will add a datapoint into the missing
|
|
|
|
+
|
|
|
|
+ # This shows up way too often. And will show up. Untill we
|
|
|
|
+ # will desing a logo.
|
|
|
|
+ if name == "favicon.ico":
|
|
|
|
+ return
|
|
|
|
+
|
|
|
|
+ # first we need to make sure that the file exists
|
|
|
|
+ try:
|
|
|
|
+ with open("data/missing.json") as json_file:
|
|
|
|
+ missing = json.load(json_file)
|
|
|
|
+
|
|
|
|
+ # Reverse the old file
|
|
|
|
+ if type(missing) == dict:
|
|
|
|
+ missing = []
|
|
|
|
+
|
|
|
|
+ except:
|
|
|
|
+ missing = []
|
|
|
|
+
|
|
|
|
+ # There could be a problem with writing so we look into it
|
|
|
|
+ # for a very close match. Up to about 60%. No more.
|
|
|
|
+
|
|
|
|
+ match_missing = 0
|
|
|
|
+ closest_missing = 0
|
|
|
|
+
|
|
|
|
+ found = False
|
|
|
|
+ for ind, n in enumerate(missing):
|
|
|
|
+ for i in n:
|
|
|
|
+ sim = similar(name, i)
|
|
|
|
+ if sim > 0.6: # At least 60% match
|
|
|
|
+ found = True
|
|
|
|
+ if match_missing < sim:
|
|
|
|
+ match_missing = sim
|
|
|
|
+ closest_missing = ind
|
|
|
|
+ if not found:
|
|
|
|
+ missing.append({name:1})
|
|
|
|
+ else:
|
|
|
|
+
|
|
|
|
+ if not name in missing[closest_missing]:
|
|
|
|
+ missing[closest_missing][name] = 1
|
|
|
|
+ else:
|
|
|
|
+ missing[closest_missing][name] += 1
|
|
|
|
+
|
|
|
|
+ # Now we save the file
|
|
|
|
+ with open("data/missing.json", 'w') as f:
|
|
|
|
+ json.dump(missing, f, indent=4, sort_keys=True)
|
|
|
|
+
|
|
|
|
+def remove(name):
|
|
|
|
+
|
|
|
|
+ # This function will remove a datapoint from the missing
|
|
|
|
+
|
|
|
|
+ try:
|
|
|
|
+ with open("data/missing.json") as json_file:
|
|
|
|
+ missing = json.load(json_file)
|
|
|
|
+
|
|
|
|
+ # Reverse the old file
|
|
|
|
+ if type(missing) == dict:
|
|
|
|
+ missing = []
|
|
|
|
+
|
|
|
|
+ except:
|
|
|
|
+ missing = []
|
|
|
|
+
|
|
|
|
+ # There could be a problem with writing so we look into it
|
|
|
|
+ # for a very close match. Up to about 60%. No more.
|
|
|
|
+
|
|
|
|
+ match_missing = 0
|
|
|
|
+ closest_missing = 0
|
|
|
|
+
|
|
|
|
+ found = False
|
|
|
|
+ for ind, n in enumerate(missing):
|
|
|
|
+ for i in n:
|
|
|
|
+ sim = similar(name, i)
|
|
|
|
+ if sim > 0.6: # At least 60% match
|
|
|
|
+ found = True
|
|
|
|
+ if match_missing < sim:
|
|
|
|
+ match_missing = sim
|
|
|
|
+ closest_missing = ind
|
|
|
|
+
|
|
|
|
+ if found:
|
|
|
|
+ del missing[closest_missing]
|
|
|
|
+
|
|
|
|
+ # Now we save the file
|
|
|
|
+ with open("data/missing.json", 'w') as f:
|
|
|
|
+ json.dump(missing, f, indent=4, sort_keys=True)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+def List():
|
|
|
|
+
|
|
|
|
+ # This function will list missing in markdown format
|
|
|
|
+
|
|
|
|
+ try:
|
|
|
|
+ with open("data/missing.json") as json_file:
|
|
|
|
+ missing = json.load(json_file)
|
|
|
|
+
|
|
|
|
+ # Reverse the old file
|
|
|
|
+ if type(missing) == dict:
|
|
|
|
+ missing = []
|
|
|
|
+
|
|
|
|
+ except:
|
|
|
|
+ missing = []
|
|
|
|
+
|
|
|
|
+ print("| Done | Best Name | Other Names |")
|
|
|
|
+ print("| --- | --- | --- |")
|
|
|
|
+ for i in missing:
|
|
|
|
+ i = sorted(i.items(), key=lambda x:x[1])
|
|
|
|
+ i = dict(i)
|
|
|
|
+
|
|
|
|
+ s = "| | **"+list(i.keys())[0]+"**"
|
|
|
|
+ if len(i) > 1:
|
|
|
|
+ s = s + " | "
|
|
|
|
+ for b in i:
|
|
|
|
+ if b == list(i.keys())[0]:
|
|
|
|
+ continue
|
|
|
|
+ comma = ", "
|
|
|
|
+ if b == list(i.keys())[-1]:
|
|
|
|
+ comma = ""
|
|
|
|
+ s = s + b + comma
|
|
|
|
+ s = s + " |"
|
|
|
|
+ else:
|
|
|
|
+ s = s + " | |"
|
|
|
|
+ print(s)
|