Python CGI script not executing when run through HTML form - html

I am trying to experiment with python's cgi module, ad do't want to buy an entire server just to accomplish this task. So I have written my html and python cgi script on my Ubuntu 14.04 computer, but the script will not run. Here is the relevant HTML code:
<form action = "cgi-bin/Login.py" method="get">
Username <input type = "text" name = "user"><br>
Password: <input type = "password" name = "password"><br>
<input type = "submit" value = "Submit"><br>
</form>
And the Python 3 Code
import cgi, cgitb
form = cgi.FieldStorage()
# Get data from fields
Username = form.getvalue('user')
Password = form.getvalue('password')
print ("Content-type:text/html")
print ()
print ("<html>")
print ("<head>")
print ("<title>Hello - Second CGI Program</title>")
print ("</head>")
print ("<body>")
print ("<h2>Hello %s %s</h2>" % (Username, Password))
print ("</body>")
print ("</html>")
And lastly the popup that I get when I click the submit button on the webpage.

You'll need to setup and configure a web server to serve the cgi scripts. Here's the apache documentation on that.

Try use POST in the form. CGI on python needs POST to works.

Related

Repeatedly getting 500 error on CGI script - frontend HTML works but not CGI [MySQL]

What I want is for a MySQL query that I wrote a few weeks ago to return values from a database based on an entered query.
Here is the HTML script:
<!DOCTYPE html>
<head>
<meta charset=UTF-8">
</head>
<p>
Search by gene product name
</p>
<form name="search" method="post" action="XXXX-CGISCRIPT-XXXX">
<input id="search_entry" type="text" name="search_entry">
<input type="submit" value="Search">
</form>
</body></html>
and here is the CGI script:
#!/usr/bin/env python3
import mysql.connector
import cgi
import jinja2
import re
from biocode import utils
import cgitb
def main():
cgitb.enable()
loadTemp = jinja2.FileSystemLoader(searchpath="./templates")
environs = jinja2.Environment(loader=loadTemp)
template = environs.get_template('search_template.html')
form = cgi.FieldStorage()
acc = form.getvalue('search_entry')
conn = mysql.connector.connect(user = 'XXX', password = 'XXX',
host = 'localhost', database = 'XXX_chado')
    # MySQL query
qry = """SELECT f.uniquename, product.value, assem.uniquename, assem_type.name, g.fmin, g.fmax, g.strand
FROM feature f
JOIN cvterm polypeptide ON f.type_id=polypeptide.cvterm_id
JOIN featureprop product ON f.feature_id=product.feature_id
JOIN cvterm productprop ON product.type_id=productprop.cvterm_id
JOIN featureloc g ON f.feature_id=g.feature_id
JOIN feature assem ON g.srcfeature_id=assem.feature_id
JOIN cvterm assem_type ON assem.type_id=assem_type.cvterm_id
WHERE polypeptide.name = 'polypeptide'
AND productprop.name = 'gene_product_name'
AND product.value LIKE %s;"""
curs = conn.cursor()
curs.execute(qry, ('%' + acc + '%',))
for  (f.uniquename,  productprop.name)  in  curs:
print(template.render(curs=curs, accs=acc))
conn.close()
curs.close()
I keep getting a 500 internal server error and I'm not quite sure why. My understanding is that search_entry on the HTML side (which works) is what the user enters into the search box to be handled by the CGI script. The query is then returned by
form = cgi.FieldStorage()
acc = form.getvalue('search_entry')
and then later passed by
curs = conn.cursor()
curs.execute(qry, ('%' + acc + '%',))
to be used in the preceding MySQL query. The last few lines send variables over to the template (whose bridge I will cross when I get there) and close the connection.
My problem, I have trouble really understanding why it is that I keep getting the error message '500 Internal Server Error'. I have tried making several changes and caught many mistakes, as well as altered the formatting, but to no avail. If it was a template error, I don't think I would getting this server error, would I? I think it's a CGI error, and
import cgitb
...
cgitb.enable()
doesn't work, so I can't get a more detailed error message, regardless of where I place cgitb.enable() or if I have it print to file within the server.
Does anyone notice any obvious code errors that I could correct to at least stop getting the error? In the interest of full disclosure, this is for a school assignment.

Passing the value from a ruby block to a resource in chef

I am writing a chef resource, which will generate a password, and I am calling that resource in a recipe with the list of inputs.
Following is my scenario: Once my resource got executed, a new set of passwords will be generated in a folder, and I want to retrieve that password which is newly generated. But I am unable to retrieve that password because the value I am trying to retrieve is executing at the convergence phase.
Simple code block to explain my scenario:
Chef::Log.info("Creating new keys")
create_password 'New Password is being generated' do
action :change_passwords
password_util_dir node[:password][:passwd_util_dir]
rgbu_chef node[:password][:rgbu_chef]
old_data_bags node[:password][:old_data_bags]
new_data_bags node[:password][:new_data_bags]
end
The code above will create new passwords in a folder.
Later, I am trying to take the passwords through a JSON Parser:
text =::File.read("#{new_password_dir}")
data_hash = JSON.parse(text)
new_wls_password = data_hash['rase_wlsadmin_pwd']
The #{new_password_dir} is the directory location of the newly created password.json file.
I am trying to use the value of "new_wls_password" in the another resource like below:
Chef::Log.info("Updating WLSADMIN Password")
passwd_backup 'Updating wlsadmin password' do
action :update_wlsadmin
osuser node[:password][:wls_config_user]
usergroup node[:password][:wls_install_group]
new_wls_password "#{new_wls_password}"
end
Here, the new password which I am trying to retrieve is empty, since the following three lines are executed in the first place:
text =::File.read("#{new_password_dir}")
data_hash = JSON.parse(text)
new_wls_password = data_hash['rase_wlsadmin_pwd']
So, by that time, the new passwords resource has not been run.
I tried many stack overflow suggestions, like:
putting those three lines in a ruby_block like this
ruby_block "new_password" do
block do
text =::File.read("#{new_password_dir}")
data_hash = JSON.parse(text)
node.set[:new_wls_password] = data_hash['rase_wlsadmin_pwd']
end
end
Then I tried fetching the value into the resource as below
Chef::Log.info("Updating WLSADMIN Password")
passwd_backup 'Updating wlsadmin password' do
action :update_wlsadmin
osuser node[:password][:wls_config_user]
usergroup node[:password][:wls_install_group]
new_wls_password "#{node[:new_wls_password]"
end
With the above approach still the value is empty
Trying the value with lazy and calling that value.
Passing the value from one ruby block to another ruby block, which I can do, but not with the resources.
Please, can you help?
EDIT #1 :
I need to pass the value from the resource to the template.
Something like this, after running the following resource:
Chef::Log.info("Creating new keys")
create_password 'New Password is being generated' do
action :change_passwords
password_util_dir node[:password][:passwd_util_dir]
rgbu_chef node[:password][:rgbu_chef]
old_data_bags node[:password][:old_data_bags]
new_data_bags node[:password][:new_data_bags]
end
A new set of passwords will be generated in a folder, like the /tmp/password.json file.
After the resource execution above I am writing a template like:
template "#{Chef::Config[:file_cache_path]}/domain.properties" do
source 'domain_properties.erb'
variables
({ :domain_name => "#{domain_name}",
:admin_url => "#{admin_url}",
:new_wls_password => "#{new_wls_password}" })
end
Here, how can I parse the newly created value of "new_wls_password" ?
You can use lazy attribute like below:-
Chef::Log.info("Updating WLSADMIN Password")
passwd_backup 'Updating wlsadmin password' do
action :update_wlsadmin
osuser node[:password][:wls_config_user]
usergroup node[:password][:wls_install_group]
new_wls_password lazy { JSON.parse(File.read("/tmp/password.json"))['rase_wlsadmin_pwd'] }
end
Template resource can be written as:-
template "#{Chef::Config[:file_cache_path]}/domain.properties" do
source 'domain_properties.erb'
variables (lazy{{ :domain_name => "#{domain_name}",
:admin_url => "#{admin_url}",
:new_wls_password => JSON.parse(File.read("/tmp/password.json"))['rase_wlsadmin_pwd'] }})
end
Output:-
* template[/tmp/kitchen/cache/domain.properties] action create
- create new file /tmp/kitchen/cache/domain.properties
- update content in file /tmp/kitchen/cache/domain.properties from none to fa22e0
--- /tmp/kitchen/cache/domain.properties 2017-01-12 03:30:13.002968715 +0000
+++ /tmp/kitchen/cache/.chef-domain20170112-11387-1ytkyk2.properties 2017-01-12 03:30:13.002968715 +0000
## -1 +1,4 ##
+domain_name= mmm
+admin_url= nnn
+new_wls_password= xH#3zIS9Q4Hc#B

Using Groovy in Confluence

I'm new to Groovy and coding in general, but I've come a long way in a very short amount of time. I'm currently working in Confluence to create a tracking tool, which connects to a MySql Database. We've had some great success with this, but have hit a wall with using Groovy and the Run Macro.
Currently, we can use Groovy to populate fields within the Run Macro, which really works well for drop down options, example:
{groovy:output=wiki}
import com.atlassian.renderer.v2.RenderMode
def renderMode = RenderMode.suppress(RenderMode.F_FIRST_PARA)
def getSql = "select * from table where x = y"
def getMacro = '{sql-query:datasource=testdb|table=false} ${getSql} {sql-query}"
def get = subRenderer.render(getMacro, context, renderMode)
def runMacro = """
{run:id=test|autorun=false|replace=name::Name, type::Type:select::${get}|keepRequestParameters = true}
{sql:datasource=testdb|table=false|p1=\$name|p2=\$type}
insert into table1 (name, type) values (?, ?)
{sql}
{run}
"""
out.println runMacro
{groovy}
We've also been able to use Groovy within the Run Macro, example:
enter code here
{run:id=test|autorun=false|replace=name::Name, type::Type:select::${get}|keepRequestParameters = true}
{groovy}
def checkSql = "{select * from table where name = '\name' and type = '\$type'}"
def checkMacro = "{sql-query:datasource=testdb|table=false} ${checkSql} {sql-query}"
def check = subRenderer.render(checkMacro, context, renderMode)
if (check == "")
{
println("This information does not exist.")
} else {
println(checkMacro)
}
{groovy}
{run}
However, we can't seem to get both scenarios to work together, Groovy inside of a Run Macro inside of Groovy.
We need to be able to get the variables out of the Run Macro form so that we can perform other functions, like checking the DB for duplicates before inserting data.
My first thought is to bypass the Run Macro and create a simple from in groovy, but I haven't been too lucky with finding good examples. Can anyone help steer me in the right direction for creating a simple form in Groovy that would replace the Run Macro? Or have suggestions on how to get the rendered variables out of the Run Macro?

Creating a comment box html form with perl processing script

I currently have a script named "test.pl" that does a variety of things and prints out HTML code to view on a webpage. One of the things I want it to do, is allow the user to type in a comment, and select which type of comment it is and the processing form of the comment box will append the comment into a file. I am not sure if I am doing this right because it doesn't seem to be working as I'm getting some errors.. here are the snippets of the code:
#!/usr/bin/perl
use warnings;
use CGI qw(:cgi-lib :standard); # Use CGI modules that let people read data passed from a form
#Initiate comment processing
&ReadParse(%in);
if ($in("comment") && $in("type") ! == "") {
$comment = $in("comment");
$type = $in("type");
WritetoFile($comment,$type);
}
sub WritetoFile {
my $input = shift;
my $type = shift;
my $file = "$type" . "_comment.txt";
open (my $fh, '>>', $file) or die "Could not open file '$file' $!";
print $fh "$input\n";
close $fh
}
The form I am using is this:
<FORM ACTION=test.pl METHOD=POST>
Comment:
<INPUT TYPE=TEXT NAME="comment" LENGTH=60>
<P>
Select Type
<SELECT NAME ="type">
<OPTION SELECTED> Animal
<OPTION> Fruit
<OPTION> Vegetable
<OPTION> Meat
<OPTION> Other
<INPUT TYPE=SUBMIT VALUE="Submit"></FORM
Any suggestions on how to make this work or even improve the process I am doing would be greatly appreciated!I would prefer to keep the processing script and the script that does the rest of my subs to be the same script (test.pl) unless this is something I have to keep separate
Your code is a bizarre mixture of old- and new-style Perl. You're using the cgi-lib compatibility layer in CGI.pm and calling its ReadParse() function using the (unnecessary since 1994) leading ampersand. On the other hand, you're using three-arg open() and lexical filehandles. I'd be interested to hear how you developed that style.
Your problem comes from your (mis-)handling of the %in hash. Your call to ReadParse() puts all of the CGI parameters into the hash, but you're using the wrong syntax to get the values out of the hash. Hash keys are looked up using braces ({ ... }), not parentheses (( ... )).
You also have some confusion over your boolean equality operators. != is used for numeric comparisons. You want ne for string comparisons.
You probably wanted something like:
ReadParse(%in);
if ($in{comment} ne "" and $in{type} ne "") {
$comment = $in{comment};
$type = $in{type};
WritetoFile($comment,$type);
}
Your $comment and $type variables are unnecessary as you can pass the hash lookups directly into your subroutine.
WritetoFile($in{comment}, $in{type});
Finally, as others have pointed out, learning CGI in 2014 is like learning to use a typewriter - it'll still work, but people will think you're rather old-fashioned. Look at CGI::Alternatives for some more modern approaches.

HTML form with dropdown forms, sending it to database

I'm tying to make a html form with a dropbox where you can choose a few options. However when I want to send this to the databse, something goes wrong. Namely that it doesn't send the variable in the name but uses the option as variable.
<select name="name">
<option value="op1">op1</option>
<option value="op2">op2</option>
<option value="op3">op3</option>
<option value="op4">op4</option>
</select>
So when submitting this, it doesn't send var name with value opX but just opX.
While in a normal form box this seems to work:
<input name="email" type="text" value="" size="79"><br>
This sends var email with value = stuff that I typed in.
I am accessing with:
$name = $_POST["name"];
How do I fix this?
You'll probably be accessing your HTML form from some server-side language like PHP or Java.
Here's a PHP example:
$varName = $_POST['name']; // Would equal op1, op2, op3 or op4
create a hidden type and add it under the </select> but within the same form.like <input type=""hidden" name"submit" value="submit">....then check whether its set or not..like in php
if(isset($_GET/POST[submit])
{
//access your form data here..like:
$x=$_GET/POST[name]
}
this is how you can be assured about whether data is set or not
If you want to save data coming from html form, you must use server-side language. ASP,ASP.NET,PHP etc. are server-side programming language.
If you will use PHP or ASP, you should use MySql as a database. If you will use ASP.NET ,you should use MSSQL as a database. If you will use ASP , you should use MS Access Database.
Example for ASP:
<%
variable = Request.Form("name")
variable2 = Request.Form("email")
Set conn=CreateObject("ADODB.Connection")
dbpath="Data Source=" & Server.MapPath("db\yourdb.mdb")& ";Provider=Microsoft.Jet.OLEDB.4.0;"
Conn.Open dbpath
sql = "INSERT INTO yourtable_name (your_field1,yur_field2) VALUES (' "&variable&" ',' "&variable2&" ')"
Conn.execute sql
%>