CSS-fu beutifying of the site. No JS
This commit is contained in:
parent
bfd9a843ef
commit
41a91c76d3
7 changed files with 72 additions and 376 deletions
|
@ -16,5 +16,11 @@
|
||||||
1650043490.4135377,
|
1650043490.4135377,
|
||||||
1650043958.2914546,
|
1650043958.2914546,
|
||||||
1650043959.0416543,
|
1650043959.0416543,
|
||||||
1650044037.8992538
|
1650044037.8992538,
|
||||||
|
1650046703.1072881,
|
||||||
|
1650046892.2908967,
|
||||||
|
1650046892.7005703,
|
||||||
|
1650046895.821551,
|
||||||
|
1650049035.9363937,
|
||||||
|
1650050029.5476623
|
||||||
]
|
]
|
31
default.css
31
default.css
|
@ -126,4 +126,35 @@ p {
|
||||||
margin-right: 5%;
|
margin-right: 5%;
|
||||||
margin-left: 5%;
|
margin-left: 5%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.searchbar {
|
||||||
|
width: 90%;
|
||||||
|
height: 70;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
margin-top: 1%;
|
||||||
|
left: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.side_found { margin-top: 100}
|
||||||
|
.footer {}
|
||||||
|
@media screen and (min-width: 1024px) {
|
||||||
|
.recomendations {
|
||||||
|
margin-left: 40%;}
|
||||||
|
|
||||||
|
.searchbar {
|
||||||
|
width: 35%;}
|
||||||
|
.footer {
|
||||||
|
width: 60%;
|
||||||
|
height: 70;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 70;
|
||||||
|
left: 40%;}
|
||||||
|
.side_found {
|
||||||
|
margin-top: 0;
|
||||||
|
width: 35%;
|
||||||
|
position: fixed;
|
||||||
|
top:100;
|
||||||
|
left:5%;} }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
16
faq.html
16
faq.html
|
@ -1,3 +1,18 @@
|
||||||
|
<style>
|
||||||
|
|
||||||
|
.test {
|
||||||
|
width: 30%;
|
||||||
|
height: 30%;
|
||||||
|
background: #928374;
|
||||||
|
position: fixed;
|
||||||
|
top: 5%;
|
||||||
|
right: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<div class="test">Some test text</div>
|
||||||
|
|
||||||
|
|
||||||
<h1>Frequently Asked Questions:</h1>
|
<h1>Frequently Asked Questions:</h1>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
@ -118,3 +133,4 @@
|
||||||
|
|
||||||
<br><br>
|
<br><br>
|
||||||
Now search for something and get a list of Free Competitors for it.
|
Now search for something and get a list of Free Competitors for it.
|
||||||
|
|
||||||
|
|
|
@ -1,360 +0,0 @@
|
||||||
# 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 + """
|
|
||||||
|
|
||||||
|
|
||||||
<!-- For each software in the list we do mostly the same things.
|
|
||||||
And here it is. First we show it's name as a link to be able
|
|
||||||
to search Free Competitors to what is found. -->
|
|
||||||
|
|
||||||
"""
|
|
||||||
page = page + "\n <a href=\"/"+name.replace(" ", "+").lower()+"\">"
|
|
||||||
page = page + "\n <h1>"
|
|
||||||
try:
|
|
||||||
page = page + '\n <img src="'+ json["links"]["icon"] + '" alt="[LOGO]" style="height:50px;"> <!-- The logo of the software in question.-->\n'
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
page = page + " "+ name +" <!-- The title of the program -->\n"
|
|
||||||
page = page + " </h1>\n </a>\n\n"
|
|
||||||
|
|
||||||
page = page + """
|
|
||||||
|
|
||||||
<!-- Next there is a short paragraph about the program.
|
|
||||||
( Often Copypasted from some official page about it ).
|
|
||||||
Which means, it may contain the terrible words "Open Source"
|
|
||||||
that hide the fact that Free Software is about User Freedom
|
|
||||||
first of all. So we are trying to link to a special page on
|
|
||||||
GNU.ORG if such a thing is found -->
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
# 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,
|
|
||||||
"<a href=\"https://www.gnu.org/philosophy/open-source-misses-the-point.en.html\">"+ops+"</a>")
|
|
||||||
page = page + "\n <p>\n "+comment+"\n </p>\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 +"<h2>Anti-Features / Problems:</h2>"
|
|
||||||
|
|
||||||
for i in l:
|
|
||||||
if i+".html" not in issues_files:
|
|
||||||
page = page + " "+i+"<br>"
|
|
||||||
else:
|
|
||||||
page = page + '<details title="Read about '+i+'">'
|
|
||||||
page = page + "<summary>  "+i+"</summary>"
|
|
||||||
issuefile = open("data/issues/"+i+".html")
|
|
||||||
page = page + "<span><p>"+issuefile.read()+"</p></span>"
|
|
||||||
page = page + "</details>"
|
|
||||||
if not free:
|
|
||||||
return page
|
|
||||||
|
|
||||||
|
|
||||||
# Links
|
|
||||||
|
|
||||||
page = page + """
|
|
||||||
<!-- To organize the buttons with the main links we are using
|
|
||||||
a table. But since I don't know what CSS file the maintainer
|
|
||||||
will choose. And I want the table to be invisible. I insert here
|
|
||||||
a bit of CSS code. -->
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
page = page + """
|
|
||||||
<style>
|
|
||||||
table, th, td {
|
|
||||||
border-right:none;
|
|
||||||
border-left:none;
|
|
||||||
border-bottom:none;
|
|
||||||
border-top:none
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<!-- And now the table itself. -->
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
page = page + "<table><tr>"
|
|
||||||
linksfilter = {"git":"source"}
|
|
||||||
links = json.get("links", {})
|
|
||||||
for website in links:
|
|
||||||
if website in ["icon"]:
|
|
||||||
continue
|
|
||||||
link = links[website]
|
|
||||||
page = page + """
|
|
||||||
|
|
||||||
<!-- Here's how to do a simple button -->
|
|
||||||
|
|
||||||
<th>
|
|
||||||
<form action=\""""+link+"""\"> <!-- You make a form with a link -->
|
|
||||||
<button title=\""""+link+"""\" type="submit">"""+linksfilter.get(website,website).upper()+"""</button> <!-- And you activare that form with a button -->
|
|
||||||
</form>
|
|
||||||
</th>
|
|
||||||
"""
|
|
||||||
|
|
||||||
page = page + "</tr></table>"
|
|
||||||
|
|
||||||
page = page + """
|
|
||||||
|
|
||||||
<!-- Details are those little collapsable things that I like to
|
|
||||||
use very much. It's very simple really. Just read the code
|
|
||||||
carefully and you will get it -->
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
# 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 = "<i>( "+str(matches)+" )</i>"
|
|
||||||
else:
|
|
||||||
matchtext = ""
|
|
||||||
page = page + "\n\n <details>"
|
|
||||||
page = page +"\n <summary>"+categories[c]+": "+matchtext+"</summary>"
|
|
||||||
|
|
||||||
for i in l:
|
|
||||||
matchtext = ""
|
|
||||||
if i.startswith("*"):
|
|
||||||
i = i[1:]
|
|
||||||
matchtext = " <i>( match )</i> "
|
|
||||||
if i+".html" in allfiles:
|
|
||||||
datapage = open("data/"+folder+"/"+i+".html")
|
|
||||||
page = page + """
|
|
||||||
|
|
||||||
<!-- Just so happened that about \""""+i+"""\" we had a file
|
|
||||||
in data/"""+folder+""" folder. So why not make a detail inside a detail,
|
|
||||||
a detail-sception, so to speak. And add the text of explanation into it. -->
|
|
||||||
|
|
||||||
"""
|
|
||||||
page = page + "<details>\n"
|
|
||||||
page = page + " <summary> "+matchtext+i+"</summary>\n"
|
|
||||||
page = page + " <span>\n <p>\n"
|
|
||||||
page = page + " " + datapage.read()+"\n"
|
|
||||||
page = page + " </p>\n </span>\n </details>"
|
|
||||||
else:
|
|
||||||
page = page + "\n <span> "+matchtext+i+"</span>\n <br>\n"
|
|
||||||
page = page + """
|
|
||||||
|
|
||||||
<!-- Just a tiny space after all the spans. So no to feel
|
|
||||||
too crowded, so to speak -->
|
|
||||||
<span><br></span>
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
return page
|
|
||||||
|
|
||||||
def suggestions(page, json):
|
|
||||||
|
|
||||||
# This function will render suggestions
|
|
||||||
|
|
||||||
page = page + """
|
|
||||||
|
|
||||||
<!-- ===========================================================
|
|
||||||
|
|
||||||
This is where ther actual competitors are starting to show!!!
|
|
||||||
|
|
||||||
============================================================ -->
|
|
||||||
|
|
||||||
<h1>Free Competitors:</h1>
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
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 + """
|
|
||||||
|
|
||||||
<!-- Sometimes the suggestion is not very good. Below 40%
|
|
||||||
of suggestion score. But it still kind of valid. So we
|
|
||||||
want to put it into the page. Only when the user clicks
|
|
||||||
something. Why not using the same old details? -->
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<details>
|
|
||||||
<summary><h1 title="Click to show more / less.">Problematic Competitors:</h1></summary>
|
|
||||||
|
|
||||||
"""
|
|
||||||
more = True
|
|
||||||
|
|
||||||
page = page +"""
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<!-- ================================================================== -->
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
page = page + "<br>Suggestion score: " + str(frac) + "%"
|
|
||||||
page = html(page, i[-1])
|
|
||||||
|
|
||||||
if more:
|
|
||||||
page = page + "</details>"
|
|
||||||
return page
|
|
||||||
|
|
||||||
def search_widget(page, address):
|
|
||||||
|
|
||||||
# Adds a search bar to the page
|
|
||||||
|
|
||||||
page = page + """
|
|
||||||
<!-- Search widget! This widget makes it possible to implement
|
|
||||||
a search feature without using a single line of JavaScript code.
|
|
||||||
In HTML, there is an input field that we can use. If we pare it
|
|
||||||
with a button into a <form>, we can get a button that activates
|
|
||||||
the search. -->
|
|
||||||
|
|
||||||
<form action="""
|
|
||||||
page = page + address
|
|
||||||
page = page + """search method="GET">
|
|
||||||
<input type="text" name="item" class="search" placeholder="Name of Software">
|
|
||||||
<button type="submit">Search</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<!-- And that's it for the search widget -->
|
|
||||||
|
|
||||||
"""
|
|
||||||
#page = page.format(ADDRESS)
|
|
||||||
|
|
||||||
return page
|
|
||||||
|
|
||||||
def source_code_link(page):
|
|
||||||
|
|
||||||
# Adds a source code link
|
|
||||||
|
|
||||||
page = page + """
|
|
||||||
|
|
||||||
<!-- This the the footer of every page -->
|
|
||||||
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<p>This website is under the GNU AGPL license.</p>
|
|
||||||
|
|
||||||
<!-- As always I want to add a bit of CSS to make tables
|
|
||||||
invisible -->
|
|
||||||
|
|
||||||
<style>
|
|
||||||
table, th, td {
|
|
||||||
border-right:none;
|
|
||||||
border-left:none;
|
|
||||||
border-bottom:none;
|
|
||||||
border-top:none
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<!-- This is self explanatory ( if you read most of the page ) -->
|
|
||||||
|
|
||||||
<table><tr>
|
|
||||||
|
|
||||||
<th><form action=https://notabug.org/jyamihud/FreeCompetitors>
|
|
||||||
<button title="See the full source code of the software that powers this website." type="submit">SOURCE</button>
|
|
||||||
</form></th>
|
|
||||||
|
|
||||||
<th><form action=/faq>
|
|
||||||
<button title="Frequently Asked Questions" type="submit">FAQ</button>
|
|
||||||
</form></th>
|
|
||||||
|
|
||||||
<th><form action=https://notabug.org/jyamihud/FreeCompetitors/issues>
|
|
||||||
<button title="Report a bug." type="submit">BUG?</button>
|
|
||||||
</form></th>
|
|
||||||
|
|
||||||
<th><form action=https://notabug.org/jyamihud/FreeCompetitors/issues/25>
|
|
||||||
<button title="Report a piece of software that's missing from the catalogue." type="submit">MISSING?</button>
|
|
||||||
</form></th>
|
|
||||||
|
|
||||||
<th><form action=https://notabug.org/jyamihud/FreeCompetitors/issues/24>
|
|
||||||
<button title="Report a mistake in data about software." type="submit">MISTAKE?</button>
|
|
||||||
</form></th></tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<!-- And this was the page of Free Competitors. No Javascript.
|
|
||||||
No crap. No trackers. No nothing. And still works. Take that
|
|
||||||
Google!!! -->
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return page
|
|
|
@ -1 +0,0 @@
|
||||||
vcs@vcs-Lenovo-IdeaPad-S145-15IWL.3286:1650042546
|
|
|
@ -24,7 +24,6 @@ def html(page, json):
|
||||||
to search Free Competitors to what is found. -->
|
to search Free Competitors to what is found. -->
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
page = page + "\n <a href=\"/"+name.replace(" ", "+").lower()+"\">"
|
page = page + "\n <a href=\"/"+name.replace(" ", "+").lower()+"\">"
|
||||||
page = page + "\n <h1>"
|
page = page + "\n <h1>"
|
||||||
try:
|
try:
|
||||||
|
@ -301,12 +300,7 @@ def source_code_link(page):
|
||||||
|
|
||||||
<!-- This the the footer of every page -->
|
<!-- This the the footer of every page -->
|
||||||
|
|
||||||
<br>
|
This website is under the GNU AGPL license.
|
||||||
<br>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<p>This website is under the GNU AGPL license.</p>
|
|
||||||
|
|
||||||
<!-- As always I want to add a bit of CSS to make tables
|
<!-- As always I want to add a bit of CSS to make tables
|
||||||
invisible -->
|
invisible -->
|
||||||
|
@ -346,9 +340,6 @@ def source_code_link(page):
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<!-- And this was the page of Free Competitors. No Javascript.
|
<!-- And this was the page of Free Competitors. No Javascript.
|
||||||
No crap. No trackers. No nothing. And still works. Take that
|
No crap. No trackers. No nothing. And still works. Take that
|
||||||
Google!!! -->
|
Google!!! -->
|
||||||
|
|
21
server.py
21
server.py
|
@ -97,9 +97,9 @@ class handler(BaseHTTPRequestHandler):
|
||||||
csstext = '<link media="all" href="'+CSS+'" type="text/css" rel="stylesheet" />'
|
csstext = '<link media="all" href="'+CSS+'" type="text/css" rel="stylesheet" />'
|
||||||
text = "<!-- Welcome to Free Competitors Page Source!!!--> \n\n"
|
text = "<!-- Welcome to Free Competitors Page Source!!!--> \n\n"
|
||||||
text = text + "<!-- Let's add some CSS, you can edit 'config.json' to change it. -->\n"
|
text = text + "<!-- Let's add some CSS, you can edit 'config.json' to change it. -->\n"
|
||||||
text = text + '<head>'+csstext+'</head>\n\n'
|
text = text + '<head>'+csstext+'\n\n'
|
||||||
text = text + "<!-- Now we want the favicon to be PNG instead of ICO -->\n\n"
|
text = text + "<!-- Now we want the favicon to be PNG instead of ICO -->\n\n"
|
||||||
text = text + '<link rel="icon" href="favicon.png">'
|
text = text + '<link rel="icon" href="favicon.png"></head>\n\n'
|
||||||
text = text + "<!-- Now the body. The main part of the page, so to speak. -->\n"
|
text = text + "<!-- Now the body. The main part of the page, so to speak. -->\n"
|
||||||
text = text + '<body>\n\n'+textin+'\n\n</body>'
|
text = text + '<body>\n\n'+textin+'\n\n</body>'
|
||||||
|
|
||||||
|
@ -211,13 +211,26 @@ class handler(BaseHTTPRequestHandler):
|
||||||
software = self.path.replace("/", "").replace("+", " ")
|
software = self.path.replace("/", "").replace("+", " ")
|
||||||
|
|
||||||
software_data, match = search.search_app(software)
|
software_data, match = search.search_app(software)
|
||||||
|
|
||||||
page = render.search_widget("", ADDRESS)
|
page = ""
|
||||||
|
page = page + '<div class="searchbar">'
|
||||||
|
page = page + render.search_widget("", ADDRESS)
|
||||||
|
page = page + "</div>"
|
||||||
|
|
||||||
|
page = page + '<div class="side_found">'
|
||||||
page = page +"Search match: "+ str(int(match*100))+"%"
|
page = page +"Search match: "+ str(int(match*100))+"%"
|
||||||
# Let's add the found software to the page
|
# Let's add the found software to the page
|
||||||
page = render.html(page, software_data)
|
page = render.html(page, software_data)
|
||||||
|
page = page + "</div>"
|
||||||
|
|
||||||
|
page = page + '<div class="recomendations">'
|
||||||
page = render.suggestions(page, software_data)
|
page = render.suggestions(page, software_data)
|
||||||
|
page = page + "</div>"
|
||||||
|
|
||||||
|
page = page + '<div class="footer">'
|
||||||
page = render.source_code_link(page)
|
page = render.source_code_link(page)
|
||||||
|
page = page + "</div>"
|
||||||
|
|
||||||
|
|
||||||
self.send(page)
|
self.send(page)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue