directory watcher, trying to match filename to directory name.

Discussion in 'Ruby' started by Brian Wallace, Apr 21, 2009.

  1. [Note: parts of this message were removed to make it a legal post.]

    Hi All,

    Here's an issue I can't seem to figure out, regardless of the hours i've
    spent pondering it...

    I'm using Directory Watcher to scan a directory for added files, if files
    are added I run my method that handles them.. This works great...

    However.. I'm trying to match the directory name to the file name , ie:

    C:\Send\Bob\Bob* will trigger the event ,but any other file added to that
    directory will not ... here's what I have - this will just fire an event for
    any file added to the observed folder.

    I set a directory , such as "C:\Send" and then only monitor the
    subdirectories of this directory .. I just need to make sure that events are
    fired _only_ when the subdirectory name matches the beginning of the file
    name.

    dw = DirectoryWatcher.new "#{@dirwatch}", :interval => 5, :glob => "*/*",
    :pre_load => true
    dw.add_observer {|*args| args.each do |a|
    if a.type == :added
    sleep(3)
    @filename = a.path
    signInAction()
    getFile(@filename)
    initDataUpload(@localFileSize, @session)
    completeSend(@fileId, @session)
    addDelivery(@localFile, @fileId, @session, @rcpt_email)
    puts "File: #{@filename} sent!!!"
    @chunkSize = 61440
    end
    end
    end}

    Any Ideas?

    Thanks,

    Brian
    Brian Wallace, Apr 21, 2009
    #1
    1. Advertising

  2. Thanks David,

    Yes I've read every bit of documentation for Directory Watcher ... I guess
    my problem is more of a generic ruby programming problem.

    I'm not sure how to dynamically change the glob pattern ...Since its set
    during the creation of the dw object .. Of course I can change it, within
    the add_observer block - with a symbol.. But the problem I'm having is
    getting the subdirectory name for matching...

    ie: C:\Send has 3 subdirectories

    C:\Send\Bob
    C:\Send\Kevin
    C:\Send\James

    I want to only match a filename that has "Bob, Kevin, or James" inside its
    respective subdirectory.

    On Tue, Apr 21, 2009 at 3:27 AM, David Gaya <> wrote:

    > > dw =3D DirectoryWatcher.new "#{@dirwatch}", :interval =3D> 5, :glob =3D=

    > "*/*",
    > :pre_load =3D> true
    > dw =3D DirectoryWatcher.new "#{@dirwatch}", :interval =3D> 5, :glob =3D>
    > "*/Bob*", :pre_load =3D> true
    >
    > From the documentation:
    > File Selection
    > The directory watcher uses glob patterns to select the files to scan.
    > The default glob pattern will select all regular files in the
    > directory of interest =92*=92.
    > Here are a few useful glob examples:
    > '*' =3D> all files in the current directory
    > '**/*' =3D> all files in all subdirectories
    > '**/*.rb' =3D> all ruby files
    > 'ext/**/*.{h,c}' =3D> all C source code files
    >
    > Regards,
    > David
    >
    > 2009/4/21 Brian Wallace <>:
    > > Hi All,
    > >
    > > Here's an issue I can't seem to figure out, regardless of the hours i'=

    ve
    > > spent pondering it...
    > >
    > > I'm using Directory Watcher to scan a directory for added files, if fil=

    es
    > > are added I run my method that handles them.. This works great...
    > >
    > > However.. I'm trying to match the directory name to the file name , ie:
    > >
    > > C:\Send\Bob\Bob* will trigger the event ,but any other file added to th=

    at
    > > directory will not ... here's what I have - this will just fire an even=

    t
    > for
    > > any file added to the observed folder.
    > >
    > > I set a directory , such as "C:\Send" and then only monitor the
    > > subdirectories of this directory .. I just need to make sure that event=

    s
    > are
    > > fired _only_ when the subdirectory name matches the beginning of the fi=

    le
    > > name.
    > >
    > > dw =3D DirectoryWatcher.new "#{@dirwatch}", :interval =3D> 5, :glob =3D=

    > "*/*",
    > > :pre_load =3D> true
    > > dw.add_observer {|*args| args.each do |a|
    > > if a.type =3D=3D :added
    > > sleep(3)
    > > @filename =3D a.path
    > > signInAction()
    > > getFile(@filename)
    > > initDataUpload(@localFileSize, @session)
    > > completeSend(@fileId, @session)
    > > addDelivery(@localFile, @fileId, @session, @rcpt_email)
    > > puts "File: #{@filename} sent!!!"
    > > @chunkSize =3D 61440
    > > end
    > > end
    > > end}
    > >
    > > Any Ideas?
    > >
    > > Thanks,
    > >
    > > Brian
    > >

    >
    >
    Brian Wallace, Apr 21, 2009
    #2
    1. Advertising

  3. Brian Wallace

    Tim Pease Guest

    On Tue, Apr 21, 2009 at 6:51 AM, Brian Wallace <> wrote:
    > Thanks David,
    >
    > =A0Yes I've read every bit of documentation for Directory Watcher ... I g=

    uess
    > my problem is more of a generic ruby programming problem.
    >
    > I'm not sure how to dynamically change the glob pattern ...Since its set
    > during the creation of the dw object .. Of course I can change it, within
    > the add_observer block - with a symbol.. But the problem I'm having is
    > getting the subdirectory name for matching...
    >
    > ie: C:\Send has 3 subdirectories
    >
    > C:\Send\Bob
    > C:\Send\Kevin
    > C:\Send\James
    >
    > I want to only match a filename that has "Bob, Kevin, or James" inside it=

    s
    > respective subdirectory.
    >


    DirectoryWatcher is not able to do what you need. It only supports
    glob patterns for matching files, and what you are in need of is
    regular expressions. The best solution is to implement the regular
    expression matching inside your observer.

    def observer_method( *args )
    args.each do |event|
    next unless event.type =3D=3D :added
    next unless event.path =3D~ %r/^#{@directory}\/([^\/]+)\/.*\1.*/
    # put your code here
    end
    end

    Also, you have a sleep method in your observer block. I would
    recommend using the "stable" event if you want to make sure that the
    file is no longer being modified before operating on it.

    Blessings,
    TwP
    Tim Pease, Apr 21, 2009
    #3
  4. [Note: parts of this message were removed to make it a legal post.]

    Hi Tim,

    Thanks for the reply, since your the developer of the gem it is really nice
    that you've taken the time to respond to my issue. You've made one of my
    _favorite_ ruby gems so far...

    Your example helps me a LOT , especially since I'm horrible at regular
    expressions :) .. I needed to show the application this morning, so I
    frantically wrote an alternative - which may be ugly, but works pretty well
    so far.. Basically, I grab all of the subdirectories of the Directory
    Watcher directory, and then create an array of glob patterns with the
    directory names, and filename ie:

    @dir = Dir.open(@dirwatch)
    parsed_dir = @dir.entries.grep(/^[^.]/).map
    parsed_glob = parsed_dir.collect {|d| d = "*#{d}/#{d}*"}

    I then just pass the parsed_glob array to the directory watcher ...

    With that said - and since I am so horrible with regular expressions ...
    Does anyone know the RegExp that will match directory names ONLY ?
    (excluding '.' and '..') The one I have above appears to match anything
    except '.' , and '..'

    Thanks,

    Brian

    On Tue, Apr 21, 2009 at 11:35 AM, Tim Pease <> wrote:

    > On Tue, Apr 21, 2009 at 6:51 AM, Brian Wallace <>
    > wrote:
    > > Thanks David,
    > >
    > > Yes I've read every bit of documentation for Directory Watcher ... I

    > guess
    > > my problem is more of a generic ruby programming problem.
    > >
    > > I'm not sure how to dynamically change the glob pattern ...Since its set
    > > during the creation of the dw object .. Of course I can change it, within
    > > the add_observer block - with a symbol.. But the problem I'm having is
    > > getting the subdirectory name for matching...
    > >
    > > ie: C:\Send has 3 subdirectories
    > >
    > > C:\Send\Bob
    > > C:\Send\Kevin
    > > C:\Send\James
    > >
    > > I want to only match a filename that has "Bob, Kevin, or James" inside

    > its
    > > respective subdirectory.
    > >

    >
    > DirectoryWatcher is not able to do what you need. It only supports
    > glob patterns for matching files, and what you are in need of is
    > regular expressions. The best solution is to implement the regular
    > expression matching inside your observer.
    >
    > def observer_method( *args )
    > args.each do |event|
    > next unless event.type == :added
    > next unless event.path =~ %r/^#{@directory}\/([^\/]+)\/.*\1.*/
    > # put your code here
    > end
    > end
    >
    > Also, you have a sleep method in your observer block. I would
    > recommend using the "stable" event if you want to make sure that the
    > file is no longer being modified before operating on it.
    >
    > Blessings,
    > TwP
    >
    >
    Brian Wallace, Apr 21, 2009
    #4
  5. On Tue, Apr 21, 2009 at 11:11 AM, Brian Wallace <> wrote:

    > With that said - and since I am so horrible with regular expressions ...
    > Does anyone know the RegExp that will match directory names ONLY ?


    There's nothing about a name that distinguishes a directory from a
    file, so the answer to that is easy: no :)

    --
    Hassan Schroeder ------------------------
    Hassan Schroeder, Apr 21, 2009
    #5
  6. [Note: parts of this message were removed to make it a legal post.]

    I do realize this :) , but if I could at least assume that "STRING" without
    the .??? is a directory, it would suffice ... Since the application will run
    in Windows there's less of a chance that a file called "STRING" would be
    placed into the list.

    So a RegEx that matches anything up to the '.' file extension and excludes
    '.' and '..' would be enough

    On Tue, Apr 21, 2009 at 2:19 PM, Hassan Schroeder <
    > wrote:

    > On Tue, Apr 21, 2009 at 11:11 AM, Brian Wallace <>
    > wrote:
    >
    > > With that said - and since I am so horrible with regular expressions ...
    > > Does anyone know the RegExp that will match directory names ONLY ?

    >
    > There's nothing about a name that distinguishes a directory from a
    > file, so the answer to that is easy: no :)
    >
    > --
    > Hassan Schroeder ------------------------
    >
    >
    Brian Wallace, Apr 21, 2009
    #6
  7. On Tue, Apr 21, 2009 at 11:28 AM, Brian Wallace <> wrote:
    > I do realize this :) , but if I could at least assume that "STRING" without
    > the .??? is a directory, it would suffice ... Since the application will run
    > in Windows there's less of a chance that a file called "STRING" would be
    > placed into the list.


    Still a dicey assumption, IMO, but

    > So a RegEx that matches anything up to the '.' file extension and excludes
    > '.' and '..' would be enough


    Something like

    irb(main):017:0> puts "wow" if /^[\w]+$/.match("foobar")
    wow
    => nil
    irb(main):018:0> puts "wow" if /^[\w]+$/.match("foo.bar")
    => nil
    irb(main):019:0>

    HTH!
    --
    Hassan Schroeder ------------------------
    Hassan Schroeder, Apr 21, 2009
    #7
  8. Brian Wallace

    Tim Pease Guest

    On Tue, Apr 21, 2009 at 12:28 PM, Brian Wallace <> wrote:
    > I do realize this :) , but if I could at least assume that "STRING" without
    > the .??? is a directory, it would suffice ... Since the application will run
    > in Windows there's less of a chance that a file called "STRING" would be
    > placed into the list.
    >
    > So a RegEx that matches anything up to the '.' file extension and excludes
    > '.' and '..' would be enough
    >


    No regular expression required ...

    Dir.glob('/root/directory/*').each do |fn|
    next unless test(?d, fn)
    # your code goes here
    end


    The "test(?d, fn)" returns true if the current filename is a directory
    and false otherwise.

    Blessings,
    TwP
    Tim Pease, Apr 21, 2009
    #8
  9. [Note: parts of this message were removed to make it a legal post.]

    I agree, not a good assumption in most cases - and its a bit wasteful since
    i'm creating an array of globs with elements that will never match (ie: a
    file with a single name in C:\send will never match unless a directory
    exists with the same name, and the same file under it)

    This is good though, thank you - just seeing these regex's in use helps me
    understand them..

    Thanks,

    Brian

    On Tue, Apr 21, 2009 at 2:46 PM, Hassan Schroeder <
    > wrote:

    > On Tue, Apr 21, 2009 at 11:28 AM, Brian Wallace <>
    > wrote:
    > > I do realize this :) , but if I could at least assume that "STRING"

    > without
    > > the .??? is a directory, it would suffice ... Since the application will

    > run
    > > in Windows there's less of a chance that a file called "STRING" would be
    > > placed into the list.

    >
    > Still a dicey assumption, IMO, but
    >
    > > So a RegEx that matches anything up to the '.' file extension and

    > excludes
    > > '.' and '..' would be enough

    >
    > Something like
    >
    > irb(main):017:0> puts "wow" if /^[\w]+$/.match("foobar")
    > wow
    > => nil
    > irb(main):018:0> puts "wow" if /^[\w]+$/.match("foo.bar")
    > => nil
    > irb(main):019:0>
    >
    > HTH!
    > --
    > Hassan Schroeder ------------------------
    >
    >
    Brian Wallace, Apr 21, 2009
    #9
  10. [Note: parts of this message were removed to make it a legal post.]

    Tim,

    This was my original idea, however this returns the full pathname - when I
    only need actual directory name to be able to form the array of glob
    patterns..

    If I could figure out how this would return just the children directory
    names of ('/root/directory'), this would be the perfect solution.

    Thanks again for all your attention, I've already learned so much.

    Brian

    On Tue, Apr 21, 2009 at 2:46 PM, Tim Pease <> wrote:

    > On Tue, Apr 21, 2009 at 12:28 PM, Brian Wallace <>
    > wrote:
    > > I do realize this :) , but if I could at least assume that "STRING"

    > without
    > > the .??? is a directory, it would suffice ... Since the application will

    > run
    > > in Windows there's less of a chance that a file called "STRING" would be
    > > placed into the list.
    > >
    > > So a RegEx that matches anything up to the '.' file extension and

    > excludes
    > > '.' and '..' would be enough
    > >

    >
    > No regular expression required ...
    >
    > Dir.glob('/root/directory/*').each do |fn|
    > next unless test(?d, fn)
    > # your code goes here
    > end
    >
    >
    > The "test(?d, fn)" returns true if the current filename is a directory
    > and false otherwise.
    >
    > Blessings,
    > TwP
    >
    >
    Brian Wallace, Apr 21, 2009
    #10
  11. On Wed, Apr 22, 2009 at 12:42 AM, Brian Wallace <> wrote=
    :
    > Tim,
    >
    > =A0This was my original idea, however this returns the full pathname - wh=

    en I
    > only need actual directory name to be able to form the array of glob
    > patterns..
    >
    > If I could figure out how this would return just the children directory
    > names of ('/root/directory'), this would be the perfect solution.


    Look up File.basename and File.dirname

    martin
    Martin DeMello, Apr 21, 2009
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ray5531

    Watcher component

    Ray5531, May 12, 2005, in forum: ASP .Net
    Replies:
    3
    Views:
    369
    =?Utf-8?B?RWx0b24gVw==?=
    May 12, 2005
  2. Stephen
    Replies:
    1
    Views:
    426
    Stephen
    Jan 13, 2006
  3. stephen

    Question on File System Watcher

    stephen, May 31, 2006, in forum: ASP .Net
    Replies:
    0
    Views:
    398
    stephen
    May 31, 2006
  4. =?Utf-8?B?QXZp?=
    Replies:
    1
    Views:
    497
    =?Utf-8?B?TWlsb3N6IFNrYWxlY2tpIFtNQ0FEXQ==?=
    May 21, 2007
  5. Jack
    Replies:
    2
    Views:
    177
Loading...

Share This Page