This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Dlcruz129's profile picture

Help with my latest program?

Started by Dlcruz129, 22 November 2012 - 05:07 PM
Dlcruz129 #1
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.
KillaVanilla #2
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
Dlcruz129 #3
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?
Dlcruz129 #4
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/nP0vzqVx

This is what my console looks like:
> backup test
Backing up file 1 with name serversettings
backup:9: bad argument: table expected, got string
KillaVanilla #5
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
Dlcruz129 #6
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/z3A8cx3J

Again, 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?
KillaVanilla #7
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.
Dlcruz129 #8
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.
KillaVanilla #9
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
Dlcruz129 #10
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
KillaVanilla #11
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.
Dlcruz129 #12
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?
Dlcruz129 #13
Posted 24 November 2012 - 02:40 PM
Hey, getting a problem.

My code: http://pastebin.com/pf7Sz9Bj

The 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?
Luanub #14
Posted 24 November 2012 - 02:49 PM
You need to concatenate the two strings. Try doing it like..

handle = fs.open(id..fileNumber, "w")
Dlcruz129 #15
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/Udypz98x
Server: http://pastebin.com/eSMjB1a4

Let'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.