Jump to content




Search engine across multiple disk drives?

networking help

29 replies to this topic

#1 Kangaroo2K1

  • Members
  • 13 posts
  • LocationEarth

Posted 27 April 2015 - 04:36 AM

Hey, I'm fairly new to CC. I'd like to make a program where you enter a keyword into the program (running, not editing) and it searches across multiple disk drives in your wired network, and shows the results. Basically I want to make a search engine for my multi-drive network. I don't really know what to do, so all help is appreciated. Thanks! :)

#2 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 27 April 2015 - 05:40 AM

You'll first want to become familiar with looping, and with tables.

The way I'd approach this would be to first take the result of fs.list("") (which returns a numerically indexed table containing the names of all the files and folders in the root of the drive), then start a loop that inspects every element in that table, removing them as it goes. When it encounters a folder, it'd fs.list() its contents and add the contents of the new table to the first. When it encounters a match for the search term, it'd add that to a third table, which is what it'd return when the first table finally emptied.

#3 Kangaroo2K1

  • Members
  • 13 posts
  • LocationEarth

Posted 27 April 2015 - 10:38 PM

View PostBomb Bloke, on 27 April 2015 - 05:40 AM, said:

You'll first want to become familiar with looping, and with tables. The way I'd approach this would be to first take the result of fs.list("") (which returns a numerically indexed table containing the names of all the files and folders in the root of the drive), then start a loop that inspects every element in that table, removing them as it goes. When it encounters a folder, it'd fs.list() its contents and add the contents of the new table to the first. When it encounters a match for the search term, it'd add that to a third table, which is what it'd return when the first table finally emptied.
Thanks for the reply. I've been trying to code this for about 4 hours now, but still getting stumped overall. Could you (or anyone else) write this so that when you run it from the computer's directory (computer's HDD) it shows the results for all drives on the network and the computer? Thanks so much!

Edited by Kangaroo2K1, 28 April 2015 - 12:30 AM.


#4 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,451 posts

Posted 28 April 2015 - 12:33 AM

We don't generally write code on request. Post what you've got so far and explain what you're stuck on and we can help.

#5 Kangaroo2K1

  • Members
  • 13 posts
  • LocationEarth

Posted 28 April 2015 - 02:30 AM

Alright, I am very bad at coding (really sorry) but here's what I got: print(fs.list"") but all I get is a value (do I not print it?), nothing shown as a result. Any way to make it show all files, and then what would I enter to have it allow me to enter a search box to refine all files, and then what would I enter to actually single out results AND for it to show me what disk its on? Again, really sorry I'm bad at this. Thanks though for the help!

#6 Creator

    Mad Dash Victor

  • Members
  • 2,168 posts
  • LocationYou will never find me, muhahahahahaha

Posted 28 April 2015 - 06:22 AM

well, it works like this:

for i,v in pairs(fs.list(path)) do
print(v)
end


#7 flaghacker

  • Members
  • 655 posts

Posted 28 April 2015 - 10:37 AM

View PostCreator, on 28 April 2015 - 06:22 AM, said:

well, it works like this:

for i,v in pairs(fs.list(path)) do
print(v)
end

That only prints the files and folders in the root folder of the current computer, not the disk drives nor the contents of folders.

#8 Kangaroo2K1

  • Members
  • 13 posts
  • LocationEarth

Posted 28 April 2015 - 11:42 AM

View Postflaghacker, on 28 April 2015 - 10:37 AM, said:

View PostCreator, on 28 April 2015 - 06:22 AM, said:

well, it works like this:

for i,v in pairs(fs.list(path)) do
print(v)
end

That only prints the files and folders in the root folder of the current computer, not the disk drives nor the contents of folders.
Alright, how would I code it to see over all drives from being run in the computer? And what would I do next? Thanks.

#9 DannySMc

  • Members
  • 1,808 posts
  • Location/home/dannysmc95

Posted 28 April 2015 - 11:52 AM

View PostKangaroo2K1, on 28 April 2015 - 11:42 AM, said:

Alright, how would I code it to see over all drives from being run in the computer? And what would I do next? Thanks.

Did you just want the names of the files or the paths too?

I have a script I use in my xPlore file manager (It will take some time to search through lots of items)

Edited by DannySMc, 28 April 2015 - 11:52 AM.


#10 DannySMc

  • Members
  • 1,808 posts
  • Location/home/dannysmc95

Posted 28 April 2015 - 11:58 AM

Use this:
function searchall()
    local function yieldFsList(startPath)
        local list = fs.list(startPath)
        for _, file in ipairs(list) do
      	    local path = fs.combine(startPath, file)
       	    if fs.isDir(path) then
       	        yieldFsList(path)
            else
                coroutine.yield(path, file)
            end
        end
    end
    return coroutine.wrap(function() yieldFsList(start or "/") end
end

results = {}
for path, name in searchall() do
    table.insert(results[1], name)
    table.insert(results[2], path)
    sleep(0)
end

local output = fs.open("searchresults", "w")
output.write(textutils.serialize(results))
output.close()

Try this, and it should generate a file for ALL the files in all disk drives...

Depending on speeds my emulator runs at 1000fps and searches the files at about 40 per second, even when taking out sleep otherwise it may error...

Edited by DannySMc, 28 April 2015 - 11:59 AM.


#11 Creator

    Mad Dash Victor

  • Members
  • 2,168 posts
  • LocationYou will never find me, muhahahahahaha

Posted 28 April 2015 - 12:21 PM

yes, this is what it should be. I was just correcting the fs.list trouble he had ;)

#12 Kangaroo2K1

  • Members
  • 13 posts
  • LocationEarth

Posted 28 April 2015 - 08:31 PM

View PostDannySMc, on 28 April 2015 - 11:58 AM, said:

Use this:
function searchall()
	local function yieldFsList(startPath)
		local list = fs.list(startPath)
		for _, file in ipairs(list) do
			  local path = fs.combine(startPath, file)
	   		if fs.isDir(path) then
	   			yieldFsList(path)
			else
				coroutine.yield(path, file)
			end
		end
	end
	return coroutine.wrap(function() yieldFsList(start or "/") end
end

results = {}
for path, name in searchall() do
	table.insert(results[1], name)
	table.insert(results[2], path)
	sleep(0)
end

local output = fs.open("searchresults", "w")
output.write(textutils.serialize(results))
output.close()

Try this, and it should generate a file for ALL the files in all disk drives...

Depending on speeds my emulator runs at 1000fps and searches the files at about 40 per second, even when taking out sleep otherwise it may error...
I put your code into the file I was trying to work with, saved it (entered code using Notepad, so there was no other formatting) and loaded into my game. After returning to my network pc I attempted to run the program, but it said in line 13 you were missing an end parenthesis. I checked to see, but it seemed to look correct. Frustrated, I deleted that file using the computer, and retyped your entire code. After another attempt, is said it was expecting <name> after search (program name I used). I had tried various combinations but it didn't seem to work. EX: search <mydoc1>, search<mydoc1>, search mydoc1, etc... What am I doing wrong here? Thanks for the awesome code, help is appreciated!

#13 Dragon53535

  • Members
  • 971 posts
  • LocationIn the Matrix

Posted 28 April 2015 - 08:49 PM

You need to edit a couple things. i'll fix that code for you.
local tArgs = {...} --# Need to grab your extra word
function searchall(start) --#Need to have it passed here so that you can choose
	    local function yieldFsList(startPath)
			    local list = fs.list(startPath)
			    for _, file in ipairs(list) do
						  local path = fs.combine(startPath, file)
					    if fs.isDir(path) then
							    yieldFsList(path)
					    else
							    coroutine.yield(path, file)
					    end
			    end
	    end
	    return coroutine.wrap(function() yieldFsList(start or "/") end) --# Someone forgot a ) here.
end
results = {}
for path, name in searchall(tArgs[1]) do --#Sending over your path
	    table.insert(results[1], name)
	    table.insert(results[2], path)
	    sleep(0)
end
local output = fs.open("searchresults", "w")
output.write(textutils.serialize(results))
output.close()
That's about all I see being wrong

#14 Kangaroo2K1

  • Members
  • 13 posts
  • LocationEarth

Posted 28 April 2015 - 09:54 PM

View PostDragon53535, on 28 April 2015 - 08:49 PM, said:

You need to edit a couple things. i'll fix that code for you.
local tArgs = {...} --# Need to grab your extra word
function searchall(start) --#Need to have it passed here so that you can choose
		local function yieldFsList(startPath)
				local list = fs.list(startPath)
				for _, file in ipairs(list) do
						  local path = fs.combine(startPath, file)
						if fs.isDir(path) then
								yieldFsList(path)
						else
								coroutine.yield(path, file)
						end
				end
		end
		return coroutine.wrap(function() yieldFsList(start or "/") end) --# Someone forgot a ) here.
end
results = {}
for path, name in searchall(tArgs[1]) do --#Sending over your path
		table.insert(results[1], name)
		table.insert(results[2], path)
		sleep(0)
end
local output = fs.open("searchresults", "w")
output.write(textutils.serialize(results))
output.close()
That's about all I see being wrong
Doesn't seem to work, say's table excepted, got nil even though the file is in one of the drives within my network. If someone does fix this, could they also post the command so I know I'm doing this right? Thanks again! :)

Edited by Kangaroo2K1, 28 April 2015 - 09:54 PM.


#15 Square789

  • Members
  • 39 posts
  • LocationUniverse:C:/MilkyWay/Sol/Earth/Europe/Germany

Posted 29 April 2015 - 01:24 PM

The code is trying to insert the name variable to the key value 1 of {results}, which doesn't exist because the table results is {}
Remove the "[1]" and "[2]" and it should works.

But you could do this:
table.insert(results, 1, name)
table.insert(results, 2, name)

Edited by Square789, 29 April 2015 - 01:26 PM.


#16 DannySMc

  • Members
  • 1,808 posts
  • Location/home/dannysmc95

Posted 29 April 2015 - 01:55 PM

View PostSquare789, on 29 April 2015 - 01:24 PM, said:

The code is trying to insert the name variable to the key value 1 of {results}, which doesn't exist because the table results is {}
Remove the "[1]" and "[2]" and it should works.

But you could do this:
table.insert(results, 1, name)
table.insert(results, 2, name)

Yeah he is using the file manager I made which contains the search function as I took it from that.

#17 Dragon53535

  • Members
  • 971 posts
  • LocationIn the Matrix

Posted 29 April 2015 - 11:48 PM

Square is correct, the indexes at 1 and 2 are not initialized to tables.

local tArgs = {...} --# Need to grab your extra word
function searchall(start) --#Need to have it passed here so that you can choose
		local function yieldFsList(startPath)
				local list = fs.list(startPath)
				for _, file in ipairs(list) do
						  local path = fs.combine(startPath, file)
						if fs.isDir(path) then
								yieldFsList(path)
						else
								coroutine.yield(path, file)
						end
				end
		end
		return coroutine.wrap(function() yieldFsList(start or "/") end) --# Someone forgot a ) here.
end
local results = {}
results[1] = {}
results[2] = {}
for path, name in searchall(tArgs[1]) do --#Sending over your path
		table.insert(results[1], name)
		table.insert(results[2], path)
		sleep(0)
end
local output = fs.open("searchresults", "w")
output.write(textutils.serialize(results))
output.close()

There we go, I fixed it again

#18 Kangaroo2K1

  • Members
  • 13 posts
  • LocationEarth

Posted 30 April 2015 - 08:27 PM

View PostDragon53535, on 29 April 2015 - 11:48 PM, said:

Square is correct, the indexes at 1 and 2 are not initialized to tables.

local tArgs = {...} --# Need to grab your extra word
function searchall(start) --#Need to have it passed here so that you can choose
		local function yieldFsList(startPath)
				local list = fs.list(startPath)
				for _, file in ipairs(list) do
						  local path = fs.combine(startPath, file)
						if fs.isDir(path) then
								yieldFsList(path)
						else
								coroutine.yield(path, file)
						end
				end
		end
		return coroutine.wrap(function() yieldFsList(start or "/") end) --# Someone forgot a ) here.
end
local results = {}
results[1] = {}
results[2] = {}
for path, name in searchall(tArgs[1]) do --#Sending over your path
		table.insert(results[1], name)
		table.insert(results[2], path)
		sleep(0)
end
local output = fs.open("searchresults", "w")
output.write(textutils.serialize(results))
output.close()

There we go, I fixed it again
Even though I have a solution to this problem, I'd still like to have this code. This time during the first run the computer hung. After rebooting I did the command and then a keyword, it then said that my keyword was not a directory. How am I supposed to search across multiple drives if I don't know what directory I need to find it in?

#19 Dragon53535

  • Members
  • 971 posts
  • LocationIn the Matrix

Posted 01 May 2015 - 12:37 AM

View PostKangaroo2K1, on 30 April 2015 - 08:27 PM, said:

Even though I have a solution to this problem, I'd still like to have this code. This time during the first run the computer hung. After rebooting I did the command and then a keyword, it then said that my keyword was not a directory. How am I supposed to search across multiple drives if I don't know what directory I need to find it in?
Another oversight, since the code will have to run over multiple drives, they'll each have a directory unique to them. However it also occurs to me that you're just looking for a specific file. Let me rewrite that code in it's entirety so that you can look for a specific file, without needing to know it's directory.

I'll edit this post when I finish it. Shouldn't be long.


local tArgs = {...}
local modem = peripheral.wrap("right")
local function findFile(fileName)
  local function recurFile(directory,searchTerm)
	for a,v in pairs(directory) do
	  if fs.isDir(v) then
		local fnd = recurFile(fs.combine(directory,v),searchTerm)
		if fnd ~= nil then
		  return fnd
		end
	  elseif v == searchTerm then
		return {true,fs.combine(directory,v)}
	  end
	end
  end
  for a,v in pairs(modem.getNamesRemote()) do
	if peripheral.getType(v) == "drive" then
	  local found = recurFile(disk.getMountPath(v),fileName)
	  if found ~= nil then
		return unpack(found)
	  end
	end
  end
end
local found,path = findFile(tArgs[1])
if found then print(path) end
Make sure you edit that modem part to whatever side your wired modem is on

Edited by Dragon53535, 01 May 2015 - 12:48 AM.


#20 Kangaroo2K1

  • Members
  • 13 posts
  • LocationEarth

Posted 01 May 2015 - 01:16 AM

View PostDragon53535, on 01 May 2015 - 12:37 AM, said:

View PostKangaroo2K1, on 30 April 2015 - 08:27 PM, said:

Even though I have a solution to this problem, I'd still like to have this code. This time during the first run the computer hung. After rebooting I did the command and then a keyword, it then said that my keyword was not a directory. How am I supposed to search across multiple drives if I don't know what directory I need to find it in?
Another oversight, since the code will have to run over multiple drives, they'll each have a directory unique to them. However it also occurs to me that you're just looking for a specific file. Let me rewrite that code in it's entirety so that you can look for a specific file, without needing to know it's directory.

I'll edit this post when I finish it. Shouldn't be long.


local tArgs = {...}
local modem = peripheral.wrap("right")
local function findFile(fileName)
  local function recurFile(directory,searchTerm)
	for a,v in pairs(directory) do
	  if fs.isDir(v) then
		local fnd = recurFile(fs.combine(directory,v),searchTerm)
		if fnd ~= nil then
		  return fnd
		end
	  elseif v == searchTerm then
		return {true,fs.combine(directory,v)}
	  end
	end
  end
  for a,v in pairs(modem.getNamesRemote()) do
	if peripheral.getType(v) == "drive" then
	  local found = recurFile(disk.getMountPath(v),fileName)
	  if found ~= nil then
		return unpack(found)
	  end
	end
  end
end
local found,path = findFile(tArgs[1])
if found then print(path) end
Make sure you edit that modem part to whatever side your wired modem is on
Ended up with bad argument: table expected, got string. Doesn't seem to like how I ended up doing the command (search alongtime ago; one of the files across my network). And I did wrap the correct wired modem to the correct side.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users