I have a bit of code that will add an amount to an array and then print
that back on the right line of a text file. Its basically a recorded
bidding system. However, is it possible to add the file location for
File.open('/path/to/file/') dynamically rather than having to create a
new bid.cgi file for every single bid. I have 12 items which need to be
edited so essentially it needs to be able to change to 12 file names and
locations.
Thanks
Adam K
(Will post code if needed)
on 2013-01-17 15:53
on 2013-01-17 16:14
On Thu, Jan 17, 2013 at 3:53 PM, Adam Kennedy <lists@ruby-forum.com> wrote: > I have a bit of code that will add an amount to an array and then print > that back on the right line of a text file. Its basically a recorded > bidding system. However, is it possible to add the file location for > File.open('/path/to/file/') dynamically rather than having to create a > new bid.cgi file for every single bid. I have 12 items which need to be > edited so essentially it needs to be able to change to 12 file names and > locations. I'm not sure what problems you are having exactly, File.open can receive a variable: a = "file.txt" File.open(File.join("home","jesus","temp",a), "w") do |f| #do your stuff end You can choose values for a and do the same stuff in different files. BTW, as you mention cgi I assume this is going to be published on the internet. I advise you to be careful about how you choose the files for security reasons. For example, don't let the files be anywhere in your filesystem or you might compromise your server. Jesus.
on 2013-01-17 16:23
Hi,
Yeah I have a File.open function opening, a file called david.txt. In
that file it has a few bit of information. One of those pieces of
information is price. £0.00. The code needs to open the text file
david.txt, add it to an array and then save it, displaying the new
price. I can do this fine, but I basically want to have it that when the
user inputs their bid via a form input and submit, it opens the file
dynamically, father than having 12 different bid.cgi files for each text
file.
Hope this explains it a bit better the code is as follows:
#Displaying information
#!/media/Apache/ruby/bin/ruby
#!/usr/local/bin/ruby
#encoding: utf-8
puts "Content-type: text/html\n\n"
#Adds information from david.txt to an array
f = File.open("../logs/david.txt")
a = f.readlines
puts "<html>"
puts "<head>"
puts "<title>David Quetta - Nothing But the Beat</title>"
puts "</head>"
puts "<body>"
puts "<p>Name :"
puts a[0]
puts "</p>"
puts "<p>Description :"
puts a[1]
puts "</p>"
puts "<p>Price :£"
puts a[2]
puts "</p>"
puts "<p>Item Number :"
puts a[3]
puts "</p>"
puts "<form method='post' action='/cgi-bin/bid.cgi'>"
puts "Bid: £<input type='text' name='bid'>"
puts "<input type='submit' value='Submit bid'>"
puts "<input type='reset' value='Reset bid'><br />"
puts "<small>Please enter in the format £0.00</small>"
puts "</form>"
puts "</body>"
puts "</html>"
#Adding bid (its broken at this stage)
#!/media/Apache/ruby/bin/ruby
#!/usr/local/bin/ruby
#Adds information from david.txt to an array
f = File.open("../logs/david.txt")
a = f.readlines
#Sets params for form data
require 'cgi'
cgi = CGI.new()
bid = cgi.params['bid']
a[2] = bid
puts "Content-type: text/html\n\n"
puts "<html>"
puts "<head><meta http-equiv=\"REFRESH\"
content=\"4;url=/cgi-bin/david.cgi\">"
puts "<title>Thank you</title>"
puts "</head>"
puts "<body>"
puts "<p>Thank you for your bid, it will now be logged and you will be
redirected now.</p>"
puts "</body>"
puts "</html>"
In the bid.cgi which is the second file, the f = File.open needs to be
changed automatically.
Thanks
Adam k
on 2013-01-17 16:31
EDIT:
Complete working code for adding bid to a file:
#!/media/Apache/ruby/bin/ruby
#!/usr/local/bin/ruby
#Adds information from david.txt to an array
f = File.open("../logs/david.txt")
a = f.readlines
#Sets params for form data
require 'cgi'
cgi = CGI.new()
bid = cgi.params['bid']
a[2] = bid
File.open('../logs/david.txt', 'w') { |f|
f.puts a[0]
f.puts a[1]
f.puts a[2]
f.puts a[3]
}
puts "Content-type: text/html\n\n"
puts "<html>"
puts "<head><meta http-equiv=\"REFRESH\"
content=\"4;url=/cgi-bin/david.cgi\">"
puts "<title>Thank you</title>"
puts "</head>"
puts "<body>"
puts "<p>Thank you for your bid, it will now be logged and you will be
redirected now.</p>"
puts "</body>"
puts "</html>"
on 2013-01-17 18:04
On 17.01.2013 15:31, Adam Kennedy wrote: > a = f.readlines > f.puts a[0] > puts "<title>Thank you</title>" > puts "</head>" > puts "<body>" > puts "<p>Thank you for your bid, it will now be logged and you will > be > redirected now.</p>" > puts "</body>" > puts "</html>" If I understand your question correctly (and I'm not 100% sure I do!), one simple way to achieve what you want with your existing code would be to have a hidden form element in the submit page that your second script reads and then determines which of your 12 files to edit. E.g: (*WARNING UNTESTED!*) Your first script looks like: #Displaying information #!/media/Apache/ruby/bin/ruby #!/usr/local/bin/ruby #encoding: utf-8 puts "Content-type: text/html\n\n" #Adds information from david.txt to an array f = File.open("../logs/david.txt") a = f.readlines puts "<html>" puts "<head>" puts "<title>David Quetta - Nothing But the Beat</title>" puts "</head>" puts "<body>" puts "<p>Name :" puts a[0] puts "</p>" puts "<p>Description :" puts a[1] puts "</p>" puts "<p>Price :£" puts a[2] puts "</p>" puts "<p>Item Number :" puts a[3] puts "</p>" puts "<form method='post' action='/cgi-bin/bid.cgi'>" puts "Bid: £<input type='text' name='bid'>" puts "<input type="hidden" name="item" value="David"> puts "<input type='submit' value='Submit bid'>" puts "<input type='reset' value='Reset bid'><br />" puts "<small>Please enter in the format £0.00</small>" puts "</form>" puts "</body>" puts "</html>" And your second script something like: #!/media/Apache/ruby/bin/ruby #!/usr/local/bin/ruby files = {'David' => '../logs/david.txt'} #Sets params for form data require 'cgi' cgi = CGI.new() bid = cgi.params['bid'] item = cgi.params['item'] #Adds information from david.txt to an array f = File.open(files[item]) a = f.readlines a[2] = bid File.open(files[item], 'w') { |f| f.puts a[0] f.puts a[1] f.puts a[2] f.puts a[3] } puts "Content-type: text/html\n\n" puts "<html>" puts "<head><meta http-equiv=\"REFRESH\" content=\"4;url=/cgi-bin/david.cgi\">" puts "<title>Thank you</title>" puts "</head>" puts "<body>" puts "<p>Thank you for your bid, it will now be logged and you will be redirected now.</p>" puts "</body>" puts "</html>" I assume this is a learning exercise, but if not you probably want to start thinking about web frameworks and a database backend as this system doesn't really scale in any sensible way. And the puts "<html>" bits burn my eyes.
on 2013-01-17 18:38
On Thu, Jan 17, 2013 at 9:03 AM, Alex Gutteridge <alexg@ruggedtextile.com> wrote: > I assume this is a learning exercise, but if not you probably want to start > thinking about web frameworks and a database backend as this system doesn't > really scale in any sensible way. And the puts "<html>" bits burn my eyes. +1 to that. This whole thing is so painfully un-Rubyish. And this -- > #Displaying information > #!/media/Apache/ruby/bin/ruby > #!/usr/local/bin/ruby > #encoding: utf-8 is just nonsensical. A shebang line *must* be the first line of a file, and having 2 different ones makes no sense at all.
on 2013-01-18 14:12
Yeah Its for a uni prodject and I have never used Ruby before so its a massive learning curve. I know it looks horrible too :( Thanks for the help ill have a look at the code you changed but i believe this is what im looking for. Adam K
on 2013-01-18 14:55
On 18.01.2013 13:12, Adam Kennedy wrote: > Yeah Its for a uni prodject and I have never used Ruby before so its > a > massive learning curve. I know it looks horrible too :( > > Thanks for the help ill have a look at the code you changed but i > believe this is what im looking for. > > Adam K IMO, as part of a learning process, generating hand written html is fine, good even: You'll understand the fine details of what is happening better, so when you do come to using a framework that abstracts the details away you'll a) be able to debug it when it breaks and b) appreciate the convenience/beauty factor.
on 2013-01-18 15:27
Yeah thanks Alex for all your help!
After looking at your code, it worked fine. Brought up the correct
information and also enabled me to bid on an item. However, I tried
adding an if function too look something like this:
if item == 'david'
files = {'david' => '../Ablums/david.txt'}
end
As you can see, I've changed the location of the files and also the
value from the form is also lowercase d for david.
The reason I am trying to do this is that I have 12 text files which
hold different information about music Albums, I need a function go do
something like this:
if item == form value
change files to {'david' => '../Albums/david.txt'}
else
if item == form value
change files to {'asher' => ../Albums/asher.txt'}
end
(sorry for the pseudo)
So I need this function to go through 12 different item names and
depending on which one was submitted through the form it needs to open a
different file.
I keep receiving this error from my error_logs:
`initialize': can't convert nil into String (TypeError), referer:
http://localhost:10000/cgi-bin/david.cgi
on line 14 where this is occuring, the line is File.open(files[item])
So basically it seems that my function is being skipped to line 14 then
it can't find the 'files' and stops working. I know this is alot of
writing and i appreciate the help alot. If you have any idea of what is
going I would love to know :)
Adam K
on 2013-01-18 16:49
Just a quick update have the whole thing put together using an else if function but everytime I add a bid i get the error: [Fri Jan 18 15:46:24 2013] [error] [client 127.0.0.1] /media/Apache/apache2/cgi-bin/bid.cgi:38:in `<main>': undefined method `files' for main:Object (NoMethodError), referer: http://localhost:10000/cgi-bin/david.cgi dont understand why its doing this!
on 2013-01-18 17:06
On 18.01.2013 14:28, Adam Kennedy wrote: > As you can see, I've changed the location of the files and also the > if item == form value > I keep receiving this error from my error_logs: > going I would love to know :) > > Adam K I think there is a fundamental misunderstanding of the idea behind my code. Instead of a series of hard-coded if/else statements don't you just need a single completely filled out 'files' Hash with separate files for each album? E.g: files = {'david' => '../Albums/david.txt', 'asher' => '../Albums/asher.txt', 'snoop' => '../Albums/snoop.txt', 'kennyg' => '../Albums/kenny.txt', 'theknife' => '../Albums/theknife.txt'} Then the File.open(files[item]) line will open the correct file based on the item given.
on 2013-01-18 17:23
WOW! I did this to begin with then thought I was doing it wrong! How stupid of me. Have edited the code correctly and now getting an error for the File.open(files[item) saying: 26:in `initialize': can't convert nil into String (TypeError), referer: http://localhost:10000/cgi-bin/david.cgi Will have a look around and see whats going on.. Thanks for you help!
on 2013-01-18 19:22
For some reason, it doesnt think that item has been filled from the Form. However it has and yet its not working :( Any ideas?
on 2013-01-18 21:58
"files[item" isn't valid. "files[item]" would be valid code...
It's case-sensitive, so maybe you have an uppercase string and you're
trying to compare it to a lowercase one? You'd get "nil" if your hash
doesn't contain the key you're entering.
Test that the hash contains the string and fail with a descriptive error
if the conditions aren't right. Like this:
if files[item].nil?
fail TypeError, "item is not in hash: #{item.inspect}\n#{files.keys}"
end
on 2013-01-18 22:10
Yeah sorry its been a long day of coding today. The code does contain the second ] after item so it does read [item]. I will have a look, ive already output the item from the form and it does contain a value so its not the form. Its more todo with the Hash. ill write that if statement into my code and ill see what it outputs. Thanks Joel :)
on 2013-01-18 22:18
Right ran the code saying that item is not a hash . Then inspecting the item outputs: ["david"] This is correct as the hidden value is david and the hash outputs all of the correct names which I have specified in the hash. The only thing that i can see is that the item is in the format of ["david"], would this be a problem when the has is looking for "david" does it could the square brackets as part of the string? Thanks Adam k
on 2013-01-18 22:41
With regard to the enormous sequence of puts, you might want to look into this: http://log.gmarik.info/2007/12/rubys-here-document...
on 2013-01-18 23:23
All fixed! Had to put in ["david"] to the Hash and its accepted the bid! Thanks to everyone that helped! Adam K
on 2013-01-19 00:09
That's not really an ideal solution, you should probably trace the origin of "item" and find out why it's giving you an array rather than a string. I suspect that replacing cgi.params['item'] with cgi['item'] would return a string, so that you don't have to format your hash key as an array.
on 2013-01-19 01:11
I think its because I was setting it to an array without realising. I was doing item = cgi.params['item'] so it was stored that way. I will have a look tomorrow as I am extremely tired! Thanks though Joel, Really appreciate all the help.
on 2013-01-19 14:30
Another alternative would be item = cgi.params['item'][0] or item = cgi.params['item'].first
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.