An example: searching for files on the network...

Do you have questions about writing plugins or scripts in Python? Meet the coders here.
Post Reply
User avatar
Bitmonster
Site Admin
Posts: 2239
Joined: Mon Feb 06, 2006 10:28 pm

An example: searching for files on the network...

Post by Bitmonster » Mon Mar 10, 2008 1:13 pm

Here is a some code I have written to solve a problem of mine, but it might be useful for others, so I post it here.

I have some more machines on my network and use them to store DVDs of mine. To play them I use my HTPC with Zoom Player. To make it more comfortable, I have a folder full of shortcuts on one machine and every shortcut links to one DVD that is somewhere located on a share on the network. I then can use Zoom Player to show me this folder full of shortcuts to have a flat list of all DVDs that are available.

So I have written a script, to scan all the shares for DVD folders and to create the shortcuts automatically.

Since I often install new machines or new HDDs on the network, I have included some code to even find every share automatically (no fixed pathes to scan).

Here is the script:

Code: Select all

# The directory to put all the shortcuts.
outpath = "\\\\Server\\Share\\Data\\DVD Shortcuts"

# The target the shortcuts should have.
# If you only want to have a shortcut to the main IFO, use this setting:
# target = "${targetPath}"
target = "C:\\Programme\\EventGhost\\EventGhost.exe"

# The arguments that should be supplied to the target.
# If you only want to have a shortcut to the main IFO, use this settings:
# arguments = ""
arguments = '-e LoadDvdFolder "${targetPath}"'

# Search inside root directories of the shares with this name. You can use
# the wildcard characters * and ?
dvdFolderName = "DVD*"


import os
import threading
import glob
import pythoncom
import win32com.client
import win32net
import win32netcon
from os.path import split, join
from string import Template


def GetSharesOfMachine(computerName, includeAdministrativeShares=False):
    """
    Returns every network share of the given machine.
    """
    resume = 0
    while 1:
        try:
            (shares, total, resume) = win32net.NetShareEnum(
                computerName,
                0,
                resume,
                win32netcon.MAX_PREFERRED_LENGTH
            )
        except:
            break
        for share in shares:
            if not includeAdministrativeShares and share['netname'].endswith("$"):
                continue
            yield "\\\\" + computerName + "\\" + share['netname'] + "\\"
        if not resume:
            break    
    

def GetMachinesOfDomain(domainName):
    """
    Returns every machine connected to the given network domain/workgroup.
    """
    adsi = win32com.client.Dispatch("ADsNameSpaces")
    nt = adsi.GetObject("", "WinNT:")
    result = nt.OpenDSObject("WinNT://%s" % domainName, "", "", 0)
    result.Filter = ["computer"]
    for machine in result:
        yield machine.Name


def ClearDirectory(directory):
    """
    Removes every shortcut inside the given directory.
    """
    directory = unicode(directory)
    for file in os.listdir(directory):
        path = join(directory, file)
        if os.path.splitext(path)[1].lower() == ".lnk":
            try:
                os.remove(path)
            except:
                print "can't remove file: %r" % path


def DoIt():
    pythoncom.CoInitialize()
    
    domainName = win32net.NetGetJoinInformation()[0]

    print "Listing machines in %s:" % domainName
    machines = []
    for machine in GetMachinesOfDomain(domainName):
        print "   ", machine
        machines.append(machine)

    print "Listing DVD shares of machines:"
    searchPathes = []
    for machine in machines:
        for share in GetSharesOfMachine(machine):
            pathes = glob.glob(join(share, dvdFolderName))
            for path in pathes:
                if os.path.isdir(path):
                    print "   ", path
                    searchPathes.append(path)

    print "Removing old shortcuts..."
    ClearDirectory(outpath)

    for searchPath in searchPathes:
        print "Scanning:", searchPath
        for root, dirs, files in os.walk(searchPath):
            if "VIDEO_TS.IFO" in files:
                head, tail = split(root)
                if tail.upper() == "VIDEO_TS":
                    head, tail = split(head)
                tail = tail.replace("_", " ")
                tail = tail.replace(".", " ")
                print "   ", tail
                path = join(outpath, tail) + ".lnk"
                d = {
                    "targetPath": join(root, "VIDEO_TS.IFO"),
                }
                eg.Shortcut.Create(
                    path, 
                    Template(target).substitute(d), 
                    Template(arguments).substitute(d)
                )
    print "Done!"
    
t = threading.Thread(target=DoIt)
t.start()
What it does is this:
1. It finds out the domain/workgroup the machine running the script is located.
2. Then it finds out every machine that is also in this domain/workgroup.
3. It finds out every shared folder every machine has.
4. It searches for folders named "DVD" inside these shares (configurable through the dvdFolderName variable)
5. It deletes every old shortcut inside the given outpath.
6. Now it searches for "VIDEO_TS.IFO" files inside the filtered shares. They can be located in any sub-directory level.
7. If the parent of a VIDEO_TS.IFO is a folder named "VIDEO_TS" it will use the parents-parent folder name for the shortcut name. Else it will use the parents name.
8. It creates a new shortcut in the outpath with the given "target" and "arguments" settings.

In my case I don't directly link the VIDEO_TS.IFO files, but link to EventGhost and use the -e argument to supply the path to the VIDEO_TS.IFO as an event payload. This way I have some more control how DVDs should be played. But you can of course directly link to the .IFO if you want (by changing the variables at the beginning of the script).

To actually play those EventGhost shortcuts, I use a macro like this:

Code: Select all

<?xml version="1.0" encoding="UTF-8" ?>
<EventGhost Version="1303">
    <Macro Name="Load DVD Folder" Expanded="True">
        <Event Name="Main.LoadDvdFolder">
        </Event>
        <Action>
            System.Execute(u'{eg.folderPath.ProgramFiles}\\Zoom Player\\zplayer.exe', u'"{eg.event.payload[0]}"', 0, False, 2, u'')
        </Action>
    </Macro>
</EventGhost>
Please post software-related questions in the forum - PMs will only be answered, if really private, thanks!

Stoffel
Experienced User
Posts: 51
Joined: Tue Feb 07, 2006 7:30 pm

Re: An example: searching for files on the network...

Post by Stoffel » Sun Mar 16, 2008 9:53 am

Don't forget to add exe file extensions at Zoomplayer :wink:

System&Files -> File extensions -> execute -> ;exe

Stephan

damdy-cash
Experienced User
Posts: 102
Joined: Tue Mar 28, 2006 6:48 am

Re: An example: searching for files on the network...

Post by damdy-cash » Sun Mar 16, 2008 1:07 pm

Hi Lars,

i got the folowwing error because of the win32netcon:

Code: Select all

14:00:25   Traceback (most recent call last):
14:00:25     Python script "3", line 23, in <module>
14:00:25       import win32netcon
14:00:25   ImportError: No module named win32netcon
Any idea whats happend?
Gruß Damdy

User avatar
Bitmonster
Site Admin
Posts: 2239
Joined: Mon Feb 06, 2006 10:28 pm

Re: An example: searching for files on the network...

Post by Bitmonster » Sun Mar 16, 2008 2:22 pm

=> latest beta
Please post software-related questions in the forum - PMs will only be answered, if really private, thanks!

damdy-cash
Experienced User
Posts: 102
Joined: Tue Mar 28, 2006 6:48 am

Re: An example: searching for files on the network...

Post by damdy-cash » Sun Mar 16, 2008 8:45 pm

jepp, fine, therewith is the error gone, but unfortunately there comes another one later in the script

Code: Select all

21:35:25   Listing DVD shares of machines:
21:35:29   Exception in thread Thread-13:
21:35:29   Traceback (most recent call last):
21:35:29     File "threading.pyc", line 486, in __bootstrap_inner
21:35:29     File "threading.pyc", line 446, in run
21:35:29     File "2", line 86, in DoIt
21:35:29     File "2", line 38, in GetSharesOfMachine
21:35:29   error: (53, 'NetShareEnum', 'Der Netzwerkpfad wurde nicht gefunden.')
21:35:29   
do you have also herefor an idea whats wrong?

Another question: Is it possible to have something like wildcards for the DVD- folder search in this script? In your example the "DVD" works for only this exact folder. I have severals folder in my network with dvd as an part of the folder name.
Gruß Damdy

User avatar
Bitmonster
Site Admin
Posts: 2239
Joined: Mon Feb 06, 2006 10:28 pm

Re: An example: searching for files on the network...

Post by Bitmonster » Sun Mar 16, 2008 9:03 pm

I've edited the script. Try it again with the new version.

Wildcards currently don't work. But you can have as many folders as you want. It is only needed, that the root of the share has a folder named "DVD". If you have subfolders inside this DVD folder like "Action", "Science Fiction" and so on, the script will also find all DVDs in these deeper sublevels.
Please post software-related questions in the forum - PMs will only be answered, if really private, thanks!

User avatar
Bitmonster
Site Admin
Posts: 2239
Joined: Mon Feb 06, 2006 10:28 pm

Re: An example: searching for files on the network...

Post by Bitmonster » Mon Mar 17, 2008 5:38 pm

I've updated the script to allow wildcards in the folder search.
Please post software-related questions in the forum - PMs will only be answered, if really private, thanks!

damdy-cash
Experienced User
Posts: 102
Joined: Tue Mar 28, 2006 6:48 am

Re: An example: searching for files on the network...

Post by damdy-cash » Mon Mar 17, 2008 6:13 pm

excelent!! thanks.

I will test it next weekend when im back from travel.
Gruß Damdy

Post Reply