1619 posts
Posted 22 November 2012 - 06:07 PM
Hey guys.
I had an idea for online backup for ComputerCraft.
Here's what it will do:
1) Get a list of all files that are not read-only.
2) Put their contents into a table.
3) Serialize the table.
4) Send it to a server, which will store each computers contents in a directory. A password will be assigned to those files.
5) The server will send the files to another computer when requested, provided that the computer has the password.
Problem:
I have almost no experience with repeating loops (for i,v, in pairs do makes 0 sense to me) I need the program to keep reading files until there are no more files to be backed up.
Can someone please point me in the right direction?
Thanks,
Dlcruz129.
278 posts
Posted 22 November 2012 - 09:35 PM
i,v in ipairs makes more sense if you use more descriptive names for your variables, and for example:
for fileNumber, fileName in ipairs(fs.list(directory)) do
print("Opening file "..fileNumber.." Name: "..fileName)
local myHandle = fs.open(fs.combine(directory, fileName), "r")
local myData = myHandle.readAll()
myHandle.close()
-- do whatever you want to with the data
end
1619 posts
Posted 23 November 2012 - 05:45 AM
i,v in ipairs makes more sense if you use more descriptive names for your variables, and for example:
for fileNumber, fileName in ipairs(fs.list(directory)) do
print("Opening file "..fileNumber.." Name: "..fileName)
local myHandle = fs.open(fs.combine(directory, fileName), "r")
local myData = myHandle.readAll()
myHandle.close()
-- do whatever you want to with the data
end
Thanks, just a quick question: I've seen people use
for i,v in pairs() do
but I've also seen pairs replaced with ipairs, like you just did. What's the difference?
1619 posts
Posted 23 November 2012 - 05:55 AM
Ok, I gave it a test and I did something wrong. Again, I'm not so good with tables and loops, so here's the program on pastebin:
http://pastebin.com/nP0vzqVxThis is what my console looks like:
> backup test
Backing up file 1 with name serversettings
backup:9: bad argument: table expected, got string
278 posts
Posted 23 November 2012 - 06:07 AM
pairs will iterate over
everything in a table, no questions asked.
However, it may not return things in order.
ipairs will only iterate over the numeric indexes of a table.
For example:
myTable = {
[1] = "First value.",
[2] = "Second value.",
[3] = "Third value.",
["string index"] = "pairs() will see this, ipairs() won't.",
[4] = "Fourth value."
}
print("ipairs() test:")
for index, data in ipairs(myTable) do
print("There is data at index"..index.." and that data is "..data..".")
end
print("iairs() test:")
for index, data in pairs(myTable) do
print("There is data at index"..index.." and that data is "..data..".")
end
As for your problem: you're trying to insert to something that is not a table.
myString = "files" -- this is a string
myTable = {} -- this is an empty table.
-- see the difference?
table.insert(myTable, "a value") -- this will work
table.insert(myString, "a value") -- this wil cause an error
Link to the fixed code:
http://pastebin.com/yEepnPS4
1619 posts
Posted 23 November 2012 - 06:10 AM
Ok, thanks, again I'm a n00b to tables, but I got a rednet error:
http://pastebin.com/z3A8cx3JAgain, my screen:
> backup test
Backing up file 1 with name serversettings
rednet:350: string expected
It appears its sending the table multiple times, can you please help me make it so that it sends the table once, when all the files are in the table?
278 posts
Posted 23 November 2012 - 06:17 AM
First off, there's a case error.
bstring is not the same thing as bString.
Second, you need to declare your tables before you use them.
files = {}
And that's all the errors I've spotted.
1619 posts
Posted 23 November 2012 - 06:18 AM
First off, there's a case error.
bstring is not the same thing as bString.
Second, you need to declare your tables before you use them.
files = {}
And that's all the errors I've spotted.
I did declare my table, look at line 5. Thanks for the case error though, I hate debugging. I can never see my mistakes. And do you know how to make it only send rednet when all the files are in a table?
Edit: tested it, it backs up all files, but I still believe it sends multiple rednet signals.
278 posts
Posted 23 November 2012 - 06:22 AM
That's easy; just put your sending code outside of the loop.
local files = {} -- declare this OUTSIDE of the loop
for fileNumber, fileName in ipairs(fs.list(dir)) do
print("Backing up file: "..fileName)
local handle = fs.open(fileName, "r")
local data = handle.readAll()
handle.close()
table.insert(files, data)
end
rednet.send( server, textutils.serialize( files ) ) -- send the files
1619 posts
Posted 23 November 2012 - 07:01 AM
Thanks, it works.
Two questions now:
I want one possible argument to be "all", and it will back up all the files on the system. How do I make it not only backup files in the main directory, but also every other directory, including Documents, config, etc.
How do I set up the receiving server? This is all I have ;)/>/>
http://pastebin.com/HY2TMX5Z
278 posts
Posted 23 November 2012 - 11:47 AM
Thanks, it works.
Two questions now:
I want one possible argument to be "all", and it will back up all the files on the system. How do I make it not only backup files in the main directory, but also every other directory, including Documents, config, etc.
How do I set up the receiving server? This is all I have ;)/>/>
http://pastebin.com/HY2TMX5Z
Here:
-- this assumes that id and msg are from rednet.receive()
msg = textutils.unserialize(msg)
if type(msg) == "table" then -- make sure that we've recieved a valid backup
fs.makeDir(id)
print("Made directory for "..id)
for fileNumber, fileData in ipairs(msg) do -- loop over the table that was sent
local handle = fs.open(fileNumber, "w")
handle.write(fileData)
handle.close()
end
end
As for looping over every directory on a system:
That's a bit more complicated.
I used recursion. I could post it here if you want.
1619 posts
Posted 23 November 2012 - 02:23 PM
Thanks, it works.
Two questions now:
I want one possible argument to be "all", and it will back up all the files on the system. How do I make it not only backup files in the main directory, but also every other directory, including Documents, config, etc.
How do I set up the receiving server? This is all I have ;)/>/>/>
http://pastebin.com/HY2TMX5Z
Here:
-- this assumes that id and msg are from rednet.receive()
msg = textutils.unserialize(msg)
if type(msg) == "table" then -- make sure that we've recieved a valid backup
fs.makeDir(id)
print("Made directory for "..id)
for fileNumber, fileData in ipairs(msg) do -- loop over the table that was sent
local handle = fs.open(fileNumber, "w")
handle.write(fileData)
handle.close()
end
end
As for looping over every directory on a system:
That's a bit more complicated.
I used recursion. I could post it here if you want.
Thanks. How complicated is recursion?
1619 posts
Posted 24 November 2012 - 02:40 PM
Hey, getting a problem.
My code:
http://pastebin.com/pf7Sz9BjThe error: startup:14: Expected string, string.
As you can see, the lines before that change the id and filenumber to a string, but the computer still thinks its an integer. Weird, huh?
1111 posts
Location
Portland OR
Posted 24 November 2012 - 02:49 PM
You need to concatenate the two strings. Try doing it like..
handle = fs.open(id..fileNumber, "w")
1619 posts
Posted 24 November 2012 - 03:00 PM
You need to concatenate the two strings. Try doing it like..
handle = fs.open(id..fileNumber, "w")
It worked, thanks, I just have 1 thing that's not really a bug, more of an inconvenience. This is part of a backup system (like Carbonite). Here are my codes:
Client:
http://pastebin.com/Udypz98xServer:
http://pastebin.com/eSMjB1a4Let's say I backup some files named Document 1, Document 2, and Document 3. They will appear on the server in the directory computerid/1, computerid/2, and computerid/3. This is supposed to happen, but it isn't user friendly. How can I get the original file names from the client to the server?
EDIT: I derped real hard. I gave you the client startup code for my OS. Updated to the actual code. ;)/>/>
Thanks,
Dlcruz129.