Django - Read and write from a plain text - python

I'm trying to read and then write from a plain text in Django.
Basically I want to open a file, get an specific word and then change it for whatever else.
Here's what I have:
def address_L1():
file = open("interfaces.txt","r")
content = file.read()
file.close()
address = re.findall('address\s(.*?)\s',open('interfaces.txt','r').read())
if address:
print address[0]
else:
print 'no Address found!'
return address[0]
Here I'm opening a file and search for the word next to address, which is 192.168.5.5 and works perfect.
def get_interfaces(request):
address = str(address_L1())
if 'address' in request.POST:
write_template(request)#This is for my writing function
return render(request, 'interfaces.html', {'address':address})
Here I'm passing to template what's in address I mean, 192.168.5.5 will be shown in template.
<form method="post" action="">{% csrf_token %}
<label for="your_name">Address: </label>
<input id="your_name" type="text" name="address" value="{{ address }}">
<br>
<input type="submit" class="btn btn-success btn-xs" value="Guardar Cambios">
</form>
Here is my html were I'm displaying my variable, There's an input Address that will show my 192.168.5.5 or whatever is in address variable.
Everything works ok until now.
Now I'm trying to write to my plain text.
def write_template(request):
if request.method == 'POST':
get_address = address_L1()
change_address_L1 = request.GET.get("address", None)#Doing something with my input field in template
filedata= None
with open('interfaces.txt', 'r') as f:
filedata = f.readlines()
filedata=filedata.replace(get_address , change_address_L1)
with open('interfaces.txt', 'wb') as f:
f.writelines(filedata)
return render(request, 'interfaces.html')
Here basically what I want to do is get what's in my input address and replace for whatever I enter, I mean when I run my code I ll see my input with 192.168.5.5 I want to delete that value and enter 192.168.0.0 and change my value. When I try so I get this error:
'list' object has no attribute 'replace'
How can I solve this? how can I successful write in my plain text properly?
What am I doing wrong? thanks in advance!!

As the error says, filedata is a list. That's because f.readlines() gives you a list, where each element is a line in the file.
If you want the whole thing as a single string, do f.read() instead.

Related

How to take txt file as input into python (flask)

Apologies in advance if this is easy but I cant figure it out.
I have a flask app which takes a txt file as an input on a webpage. I then want to run some python scripts on it and then export it back to the website user. I'm pretty much there but I just cant figure out how to get the txt file into python.
HTML
<div class="file_input">
<form action="." method="POST">
<input type="file" name = "txt_file">
<input type="submit" name="submit_form">
</form>
</div>
Python (Flask)
#app.route('/landing')
def landing():
return render_template('index.html',
PageTitle = "Landing page")
#app.route('/', methods = ['POST'])
def test():
text_file = request.form['txt_file']
book_io = open(text_file, "r", encoding = "UTF-8")
book_str = book_io.read()
book_str
return book_str
This isn't working as it's just taking the inputted text file as a string and then printing out this string.
I basically need to know how to import the text from the file into python, but I cant figure out how.
Thanks a lot in advance!!

HTML input of type time in flask - how to autocomplete minutes/seconds if missing

I'm using a form with a submit button that is processed through Flask in order to add a new task (a row) in a SQLite database called tasks.
Here is the HTML <div/> container with the respective block content for the Flask part:
<div class="container">
{% block content %}
<form name="task_form" method="post" action="">
{{ form.csrf_token }}
<input type="text" name="task_title" placeholder="Title..."/>
<input type="text" name="task_description" placeholder="Description..."/>
<input type="date" name="task_date_due" placeholder="Due date..."/>
<input type="time" name="task_clock_due" placeholder="Due date (clock)..." step="1"/>
<input type="submit" name="task_submit" value="Add task"/>
</form>
{% endblock %}
</div>
On the Python side I have the following function that processes the GET and POST requests for the specific page:
#app.route('/db', methods=['GET', 'POST'])
def db():
# Create form
form = TaskForm(request.form)
# Initialize DB connection
init_db_conn()
# Handle POST request
if request.method == 'POST':
# Get form data
title = request.form['task_title']
description = request.form['task_description']
date = request.form['task_date_due']
time = request.form['task_clock_due']
if title != '' and description != '' and date != '' and time != '':
str_dtime = date + ' ' + time
db_conn = get_db_conn()
create_task(db, title, description, str_dtime)
elif request.method == 'GET':
pass
db_conn = get_db_conn()
cur = db_conn.cursor()
cur.execute('SELECT * FROM tasks')
tasks = cur.fetchall()
tmp = render_template('db.html', form=form, tasks=tasks)
return tmp
I'm new to Flask, my HTML skills are pretty rusty so I might be missing something but whenever I submit the data from my form through the page, I haven't entered the full time stamp (I use separate date and time inputs to allow using the calendar popup and time formatted field; can be done in a better way but for now it's what it is), I get empty string.
Example:
If I have entered 08:00:-- PM I will get empty string
If I have entered 08:--:-- PM I will get empty string.
What I was expecting is to get an autocompletion of the minutes/seconds as long as the hour has been selected.
Example:
If I have entered 08:00:-- PM I will get 08:00:00 PM (internally depending on the format I have picked on the Python side it will be converted to 20:00:00)
If I have entered 08:--:-- PM I will get 08:00:00 PM (internally depending on the format I have picked on the Python side it will be converted to 20:00:00)
Is there an easy way to fix this behaviour or do I have to create a custom input field? I can probably add a default value or just the current time as value to prevent this but it just goes around the issue. In case the user deletes the default value to enter another one and forgets to fill all the info, the problem will occur again.
I don't think you can get it to auto-complete the missing values in the HTML, but you could always set the default to 00:00:00 for example, then if they only change the hour the seconds and minutes are still at zero. They could still delete the 0's but you could get around this using a validator which won't let them enter an invalid time:
<input type="time" name="task_clock_due" placeholder="Due date (clock)..." step="1", value="00:00:00"/>
<span class="validity"></span>

Working in Python cgi with form. Empty input error

I am trying to work with forms on python and I have 2 problems which I can't decide for a lot of time.
First if I leave the text field empty, it will give me an error. url like this:
http://localhost/cgi-bin/sayHi.py?userName=
I tried a lot of variants like try except, if username in global or local and ect but no result, equivalent in php if (isset(var)). I just want to give a message like 'Fill a form' to user if he left the input empty but pressed button Submit.
Second I want to leave what was printed on input field after submit(like search form). In php it's quite easy to do it but I can't get how to do it python
Here is my test file with it
#!/usr/bin/python
import cgi
print "Content-type: text/html \n\n"
print """
<!DOCTYPE html >
<body>
<form action = "sayHi.py" method = "get">
<p>Your name?</p>
<input type = "text" name = "userName" /> <br>
Red<input type="checkbox" name="color" value="red">
Green<input type="checkbox" name="color" value="green">
<input type = "submit" />
</form>
</body>
</html>
"""
form = cgi.FieldStorage()
userName = form["userName"].value
userName = form.getfirst('userName', 'empty')
userName = cgi.escape(userName)
colors = form.getlist('color')
print "<h1>Hi there, %s!</h1>" % userName
print 'The colors list:'
for color in colors:
print '<p>', cgi.escape(color), '</p>'
On the cgi documentation page are these words:
The FieldStorage instance can be indexed like a Python dictionary. It allows membership testing with the in operator
One way to get what you want is to use the in operator, like so:
form = cgi.FieldStorage()
if "userName" in form:
print "<h1>Hi there, %s!</h1>" % cgi.escape(form["userName"].value)
From the same page:
The value attribute of the instance yields the string value of the field. The getvalue() method returns this string value directly; it also accepts an optional second argument as a default to return if the requested key is not present.
A second solution for you might be:
print "<h1>Hi there, %s!</h1>" % cgi.escape(form.getvalue("userName","Nobody"))

missing "pass" in view

{{extend 'layout.html'}}
{{import xml.etree.ElementTree as ET}}
<h1>
This is a Stations detail page
</h1>
{{filename = xmlfile}}
{{fh = open(filename, "r")}}
{{while True:}}
{{line = fh.readline()}}
{{print(line, end="")}}
{{fh.close()}}
{{=BEAUTIFY(response._vars)}}
The above code is showing "missing "pass" in view" error in web2py. Not sure why this error is showing up
Unlike in real Python, the indentation in a web2py view is only aesthetic. You need to clearly specify where the while block ends by adding pass at its end. Also note that you don't need to constantly close and open the brackets like this, you can escape all the code in only one {{ ... }}.
{{
filename = xmlfile
fh = open(xmlfile, "r")
while True:
line = fh.readline()
print(line, end="")
pass
fh.close()
}}
More informations about web2py views here.

Python and HTML: Assign a variable to a submit button

I'm writing this to a text file which is then read in by my browser. How do I assign the variable "i[0]" to the to the "submit" button so it is passed to my edit_python script?
k.write('<table>')
for i in row:
k.write('<tr>')
k.write('<td><form action="edit_python" method="post" name="edit_python"><input type="submit" value="Submit" /><></FORM></td><td>'+i[0]+'</td><td>'+i[1]+'</td>')
k.write('</tr>')
k.write('</table>')
Put it in a hidden input element. In this case, it will be assigned to the ivalue post request variable.
k.write('<table>')
for i in row:
k.write('<tr>')
k.write('<td><form action="edit_python" method="post" name="edit_python"><input type="hidden" name="ivalue" value="' + i[0] + '"/><input type="submit" value="Submit" /></form></td><td>'+i[0]+'</td><td>'+i[1]+'</td>')
k.write('</tr>')
k.write('</table>')
I cleaned up your HTML a bit too, what was this about before the end form tag?
<></FORM>
If you want a literal <> in your page, use <>. Also, the case of the tags should match for HTML, and should be lowercase for XHTML (which you appear to be using).
EDIT:
I'm writing this to a text file which is then read in by my browser
Also, you do realise the browser won't interpret Python? You need a web server set up correctly to do that.
You want to pass the i[0] attribute to your edit_python script? I think you're looking for a hidden field. So you would modify your script to write out:
Also when using Python variables in strings, I recommend not using the method you did. Check out Python string formatting for some great examples.
I also modified your write method to use dictionary passing for the attributes, which works well when you are calling the same variable multiple times in a stirng.
k.write('<table>')
for i in row:
k.write('<tr>')
k.write('<td><form action="edit_python" method="post" name="edit_python">
<input type="hidden" name="some_attr" value="%(some_attr)s" />
<input type="submit" value="Submit" /></form>
</td><td>%(some_attr)s</td><td>%(some_other_attr)s</td>'
% {"some_attr": i[0], "some_other_attr": i[1]})
k.write('</tr>')
k.write('</table>')

Categories