Using Twitter-Bootstrap in Python 3.3 Server File - python

I'm currently in the proccess of editing the html in the Python 3.3 http server code. I am doing this so I can access my media files from anywhere in my LAN. The default interface is quite boring, so I wanted to spruce it up a bit with Twitter Bootstrap buttons. The below code is from my edited server.py file, starting on line 740 (please excuse the lack of editing or elegance):
title = 'Media Listing on Computer'
r.append('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" '
'"http://www.w3.org/TR/html4/strict.dtd">')
r.append('<html>\n<head>')
r.append('<meta http-equiv="Content-Type" '
'content="text/html; charset=%s">' % enc)
r.append('<title>%s</title>\n<link href="file:///C:/Server/bootstrap.css" rel="stylesheet">\n<style type="text/css">a:link {color:grey; text-decoration: none;}</style>\n</head>' % title)
r.append('<body>\n<FONT FACE="arial" COLOR="grey">\n<h1>%s</h1>' % title)
#<body style="background-color:#B4F200;>
#<FONT FACE="courier" COLOR="grey">
r.append('<ul class="nav nav-pills nav-stacked">')
for name in list:
fullname = os.path.join(path, name)
displayname = linkname = name
# Append / for directories or # for symbolic links
if os.path.isdir(fullname):
displayname = name
linkname = name + "/"
if os.path.islink(fullname):
displayname = name + "#"
# Note: a link to a directory displays with # and links with /
r.append('<li class="active">%s</li>'
% (urllib.parse.quote(linkname), html.escape(displayname)))
r.append('</ul>\n</body>\n</html>\n')
encoded = '\n'.join(r).encode(enc)
f = io.BytesIO()
f.write(encoded)
f.seek(0)
self.send_response(200)
self.send_header("Content-type", "text/html; charset=%s" % enc)
self.send_header("Content-Length", str(len(encoded)))
self.end_headers()
return f
This generates a page with the following html:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=mbcs">
<title>Media Listing on Computer</title>
<link href="file:///C:/Server/bootstrap.css" rel="stylesheet">
<style type="text/css">a:link {color:grey; text-decoration: none;}</style>
</head>
<body>
<FONT FACE="arial" COLOR="grey">
<h1>Media Listing on Computer</h1>
<ul class="nav nav-pills nav-stacked">
<li class="active">FRAPS</li>
<li class="active">iTunes</li>
<li class="active">Misc videos</li>
<li class="active">Movies</li>
<li class="active">TV</li>
</ul>
</FONT>
</body>
</html>
Now when I open the html in a web browser it works fine, in that it loads the Twitter Bootstrap UI, however, when I run the python server, the UI doesn't load. I would really like to know how I can fix this, so if someone could give me a hand in sorting this out, that would be appreciated.

Does your browser know you are using the correct stylesheet? Maybe try using a relative path for bootstrap instead of an absolute file:///C:/Server/bootstrap.css?
UPDATE (from comments)
You placed bootstrap in a directory outside of the server root directory, so your browser wasn't able to access the css and render it. Move bootstrap into the server directory (e.g. C:\Server\lib\http\bootstrap\) and update the stylesheet path accordingly (e.g. <link href="/bootstrap/bootstrap.css" rel="stylesheet">)

Related

HTML Output in Pyscript

I was experimenting in Pyscript and I tried to print an HTML table, but it didn't work. It seems to delete the tags and mantain just the plain text.
Why is that? I tried to search online, but being a new technology i didn't find much.
This is my code:
<py-script>
print("<table>")
for i in range (2):
print("<tr>")
for j in range (2):
print("<td>test</td>")
print("</tr>")
print("</table>")
</py-script>
And this is the output I get:
I tried to replace the print() method with the pyscript.write() method, but it didn't work too.
I dig in source code pyscript.py
and at this moment works for me only code similar to JavaScript
For example this adds <h1>Hello</h1>
<div id="output"></div>
<py-script>
element = document.createElement('h1')
element.innerText = "Hello"
document.getElementById("output").append(element)
</py-script>
Full working code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>PyScript Demo</title>
<!--<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />-->
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>
<body>
<div id="output"></div>
<py-script>
element = document.createElement('h1')
element.innerText = "Hello"
document.getElementById("output").append(element)
</py-script>
</body>
</html>
EDIT:
After digging in source code I found that pyscript.js runs function htmlDecode() which removes all tags from code in <py-script> (and probably it also removes tags when you load code from file) and this makes problem.
See Pyscript issue: [BUG] print() doesn't output HTML tags. · Issue #347 · pyscript/pyscript
Some workaround is to use some replacement - ie. {{ }} instead of < > in code - and later use code to replace it back to < >
print( "{{h1}}Hello{{/h1}}".replace("{{", "<").replace("}}", ">") )
or more universal - using function for this
def HTML(text):
return text.replace("{{", "<").replace("}}", ">")
print( HTML("{{h1}}Hello{{/h1}}") )
pyscript.write(some_id, HTML("{{h1}}Hello{{/h1}}") )
document.getElementById(some_id).innerHTML = HTML("{{h1}}Hello{{/h1}}")
Sometimes problem can be also pyscript.css which redefines some items and ie. <h1> looks like normal text.
One solution is to remove pyscript.css.
Other solution is to use classes from pyscript.css like in examples/index.html
<h1 class="text-4xl font-bold">Hello World</h1>
which means
print( HTML('{{h1 class="text-4xl font-bold"}}Hello{{/h1}}') )

Correct way of hard-coding html code in python script?

I have developed a web-based tool, and currently trying to make it python-launchable. I figured using CEFpython is probably the way to do it. I followed the tutorial here and wrote the following code:
from cefpython3 import cefpython as cef
import base64
import platform
import sys
import threading
import os
HTML_code = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link href="static/css/main.css" rel="stylesheet" />
</head>
<body>
<div id="UI">
</div>
<div id="container"></div>
<script src="static/main.js"></script>
<script type="text/javascript">
function defineData(datainput){
console.log("start")
data = datainput;
var loc = window.location.pathname;
var dir = loc.substring(0, loc.lastIndexOf('/'));
console.log(loc);
console.log(dir);
Main();
}
</script>
</body>
</html>
"""
def html_to_data_uri(html):
html = html.encode("utf-8", "replace")
b64 = base64.b64encode(html).decode("utf-8", "replace")
ret = "data:text/html;base64,{data}".format(data=b64)
return ret
def main(config):
sys.excepthook = cef.ExceptHook # To shutdown all CEF processes on error
settings = {}
cef.Initialize(settings=settings)
browser = cef.CreateBrowserSync(url=html_to_data_uri(HTML_code),window_title="Test")
browser.SetClientHandler(LoadHandler(config))
cef.MessageLoop()
cef.Shutdown()
return
class LoadHandler(object):
def __init__(self, config):
self.config = config
def OnLoadingStateChange(self, browser, is_loading, **_):
"""Called when the loading state has changed."""
if not is_loading:
# Loading is complete. DOM is ready.
browser.ExecuteFunction("defineData", self.config)
unfortunately, unlike in the tutorial, my tool has to load a local .js file where the main function is defined (), and it seems if I code the html file this way, my working directory is not actually the directory where I call the script, but some strange place
the output of these lines are:
var loc = window.location.pathname;
var dir = loc.substring(0, loc.lastIndexOf('/'));
console.log(loc);
console.log(dir);
output:
text/html;base64,CjwhRE9DVFlQRSBodG1sPgo8aHRtbCBsYW5nPSJlbiI+Cgk8aGVhZD4KCQk8bWV0YSBjaGFyc2V0PSJ1dGYtOCI+CgkJPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgdXNlci1zY2FsYWJsZT1ubywgbWluaW11bS1zY2FsZT0xLjAsIG1heGltdW0tc2NhbGU9MS4wIj4KCQk8bGluayBocmVmPSJzdGF0aWMvY3NzL21haW4uY3NzIiByZWw9InN0eWxlc2hlZXQiIC8+CgkJPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCQkJKiB7CgkJCQkuYm9yZGV....
text
Could you help me finding the correct way of hard coding html code in python with the correct path? maybe I need to somehow set the path?
PS: I did try including the html code in a separate .html file, and it worked on Windows machines, but it seems MacOS doesn't like it. Since this tutorial did work on MAC, I'm trying to hard code the html part into the python script and hope it would work on both Windows and Mac
Well, the HTML document has been converted to the body of a data URI by html_to_data_uri, so the U[niversal]R[esource]L[ocator] (window.location) of the document isn't a location on a server, but the data URI itself (the "strange place" you mention).
Remember that URLs are a subset of URIs, and you passed the URI as a URL to CEF with:
browser = cef.CreateBrowserSync(url=html_to_data_uri(HTML_code),window_title="Test")
So, as long as you are using a data URI/URL, I don't think that window.location will be helpful. Instead, you could extract the HTML code into a separate .html file, and change that line to:
browser = cef.CreateBrowserSync(url="/path/to/that_html_file.html", window_title="Test")

How to import library using Brython

I wish to import my own library in Brython. This page of the documentation purports to show how, by adding the appropriate directory to the python path, but I can't make it work because I can't make Brython import sys.
Here's the simplest example code from the first page of the Brython documentation:
<html>
<head>
<script src="../src/Brython3.2.8/brython.js"></script>
</head>
<body onload="brython()">
<script type="text/python">
from browser import document, alert
def echo(ev):
alert(document["zone"].value)
document['mybutton'].bind('click', echo)
</script>
<input id="zone"><button id="mybutton">click !</button>
</body>
</html>
And that works fine.
But if I try to import sys:
<html>
<head>
<script src="../src/Brython3.2.8/brython.js"></script>
</head>
<body onload="brython()">
<script type="text/python">
import sys
from browser import document, alert
def echo(ev):
alert(document["zone"].value)
document['mybutton'].bind('click', echo)
</script>
<input id="zone"><button id="mybutton">click !</button>
</body>
</html>
Then the html will display but the button will not do anything.
The Console on Chrome shows the following error:
brython.js:6929 XMLHttpRequest cannot load file:///C:/Users/XXXXXXXXX/XXXXXX/src/Brython3.2.8/Lib/sys.py?v=1476283159509. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
$download_module # brython.js.6929
import_py # brython.js.6929
exec_module # brython.js.6929
etc etc
So, how can I import sys in brython, and/or how can I import my own library in python?
Thanks.
You need to include brython_stdlib.js in your html code. So your html should look like this:
<html>
<head>
<script src="../src/Brython3.2.8/brython.js"></script>
<script src="../src/Brython3.2.8/brython_stdlib.js"></script>
</head>
<body onload="brython()">
<script type="text/python">
import sys
from browser import document, alert
def echo(ev):
alert(document["zone"].value)
document['mybutton'].bind('click', echo)
</script>
<input id="zone"><button id="mybutton">click !</button>
</body>
</html>
Source Code : https://github.com/imvickykumar999/Brython/blob/master/index.html#L36
Deployed Code : https://imvickykumar999.github.io/Brython/
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Brython</title>
<script
type="text/javascript"
src="https://cdn.jsdelivr.net/npm/brython#3.8.9/brython.min.js">
</script>
<script
type="text/javascript"
src="https://cdn.jsdelivr.net/npm/brython#3.8.9/brython_stdlib.js">
</script>
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk"
crossorigin="anonymous">
</head>
<body onload="brython()">
<style>
body {
/* background-color: yellow; */
background-image: url(https://images.unsplash.com/photo-1573196872258-41425124bf5d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80);
/* background-repeat: no-repeat; */
}
</style>
<script type="text/python">
from browser import document
def calc(a, b, o):
d = { '+' : a+b,
'-' : a-b,
'*' : a*b,
'/' : a/b,
'%' : a%b
}
return f"({a}{o}{b})=({d[o]})"
a = float(input('Enter first number : '))
b = float(input('Enter second number : '))
o = input('Enter the Operator (+,-,*,/,%) : ')
document <= calc(a, b, o)
</script>
</body>
</html>
Brython cannot import from any Python package that is part of any Python installation on the user's computer. It works by transpiling to JavaScript and running in the browser's Javascript engine. It has no knowledge of any local Python installations, and does not require any such installations to exist.
To use Python's standard library
Add a script tag to include brython_stdlib.js as well as the base brython.js. Several CDNs provide this already.
The Brython implementation of the Python standard library does not match the reference implementation exactly. See the documentation for details on what is included and how it is organized.
Importing your own code from within the document
For organizational purposes, Python code within the HTML document can be split across multiple <script> tags. The id attribute for the tag gives a "module name" that can be used in import statements in other scripts, as long as that script has already executed. The documentation includes an example:
<script type="text/python" id="module">
def hello():
return "world"
</script>
<script type="text/python">
from browser import document
import module
document.body <= module.hello()
</script>
The browser will have loaded the first <script> tag first, creating a (JavaScript representation of) a Python module named module that contains the hello function. The second script tag will be able to import that module and use the function as usual in Python.
Importing your own code from the server
Make the files available in the appropriate place as described in the documentation. Brython's implementation of the import statement (equivalently, __import__ builtin function) will attempt to find the code on the server using AJAX.
Importing your own code as a compiled Brython package
As explained in the documentation, use the Brython package (pip install brython) to create a JavaScript file that represents the Python code. (For third-party libraries, also check if such a JavaScript file is already available from a CDN.)
Suppose we have a project that creates a package named example. Navigate to the folder that contains that package (either src or the project folder, according to how the project is organized), then run brython-cli make_package example.
This should generate a example.brython.js file. Put it somewhere on the server, and configure the server to host that file at a specific URL. Then add the corresponding tag to the client page source (or the template that generates that page).
After that it should be possible to import example, from example import ... etc. in the Brython code.
Alternately, use brython-cli modules, as described in the 'Optimization' section, to create a combined library JavaScript file representing the entire server-side part of the project.

python -m SimpleHttpServer [port] on OSX

I created simplest html page
<html lang="en">
<head>
<meta charset="utf-8">
<title>App</title>
</head>
<body>
Hello, world.
</body>
</html>
and run python -m SimpleHTTPServe 8000 in the page's folder.
Problem: When I go to localhost:8000 I see the text of my page. Means the http server instead of interpreting it as html page wraps each string of my page into <p> tag.
If I open sources I get:
<html>
........
<body>
<p class="p1"><span class="s1"><</span><b>html</b><span class="s2"> </span><span class="s3">lang</span><span class="s1">=</span><span class="s4">"en"</span><span class="s1">></span></p>
<p class="p2"> <span class="s1"><</span><span class="s5"><b>head</b></span><span class="s1">></span></p>
<p class="p2"> <span class="s1"><</span><span class="s5"><b>meta</b></span> <span class="s3">charset</span><span class="s1">=</span><span class="s4">"utf-8"</span><span class="s1">></span></p>
<p class="p3"><span class="s2"> </span><<span class="s5"><b>title</b></span>>Backbone.js Todo App</<span class="s5"><b>title</b></span>></p>
<p class="p2"> <span class="s1"></</span><span class="s5"><b>head</b></span><span class="s1">></span></p>
<p class="p2"> <span class="s1"><</span><span class="s5"><b>body</b></span><span class="s1">></span></p>
<p class="p3"><span class="s2"> </span>Hello, world.</p>
<p class="p3"><span class="Apple-converted-space"> </span></<span class="s5"><b>body</b></span>></p>
<p class="p1"><span class="s1"></</span><b>html</b><span class="s1">></span></p>
</body>
</html>
If you're editing your page in TextEdit, make sure you open the Format menu and choose "Make Plain Text."
If you saved as HTML without this option, TextEdit would have added those tags to keep your text file's formatting.
I just tried on my mac and I don't observe similar behaviour: I start server slightly differently:
python -mSimpleHTTPServer 8000 : no space between m and SimpleHTTPServer (checked with space, same behaviour)
I have 2 files : a.out and a.html with same content : it looks like a.out gets downloaded while a.html gets displayed (with chrome)
My guess is that your file has no extension .html and that your browser itself is adding the tags to display it.
You can try downloading the file with curl to make sure : curl http://localhost:8000/a.out from a terminal
Note : I'm running MacOS 10.9.4 on a McBook air with python 2.7.5
If your page show up as text just as you are describing then that most likely means that the server does not use the correct content-type in its HTTP headers. SimpleHTTPServer uses the module mimetypes to determine what content-type to use for most file types.
You can check it yourself:
>>> import mimetypes
>>> mimetypes.init()
>>> print mimetypes.types_map
...
or more specifically
>>> print mimetypes.types_map['.html']
text/html
Make sure your file extension matches with what mimetypes expects.

In Python, I can print HTML to the browser, how can I ensure that the CSS that relates to it also get "printed"

// After the "Content-type..." declaration...
print """<html>\
<head>
<title>Create Survey</title>
<link href="styles.css" type="text/css" rel="stylesheet">
</head>
<body>...."""
Assuming you are using something like CGI to "print" text based on a web request you should rely on your web server (Apache for example) to "print" the content back to the requesting client based on where your CSS file is located in the htdocs directory.
However if you are just wanting some output in a command line window you could do...
print file('/path/to/your/file/styles.css').read()

Categories

Resources