Directory watcher, trying to match filename to directory name

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

dw = DirectoryWatcher.new "#{@dirwatch}", :interval => 5, :glob => "*/*", :pre_load => true

dw = DirectoryWatcher.new "#{@dirwatch}", :interval => 5, :glob =>
"*/Bob*", :pre_load => 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 ’*’.
Here are a few useful glob examples:
    '*' => all files in the current directory
    '**/*' => all files in all subdirectories
    '**/*.rb' => all ruby files
    'ext/**/*.{h,c}' => all C source code files

Regards,
David

···

2009/4/21 Brian Wallace <draygen80@gmail.com>:

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

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 <david.gaya@gmail.com> wrote:

> dw = DirectoryWatcher.new "#{@dirwatch}", :interval => 5, :glob => "*/*",
:pre_load => true
dw = DirectoryWatcher.new "#{@dirwatch}", :interval => 5, :glob =>
"*/Bob*", :pre_load => 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 ’*’.
Here are a few useful glob examples:
   '*' => all files in the current directory
   '**/*' => all files in all subdirectories
   '**/*.rb' => all ruby files
   'ext/**/*.{h,c}' => all C source code files

Regards,
David

2009/4/21 Brian Wallace <draygen80@gmail.com>:
> 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
>

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

···

On Tue, Apr 21, 2009 at 6:51 AM, Brian Wallace <draygen80@gmail.com> 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.

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 :slight_smile: .. 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 <tim.pease@gmail.com> wrote:

On Tue, Apr 21, 2009 at 6:51 AM, Brian Wallace <draygen80@gmail.com> > 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

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

···

On Tue, Apr 21, 2009 at 11:11 AM, Brian Wallace <draygen80@gmail.com> wrote:

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

--
Hassan Schroeder ------------------------ hassan.schroeder@gmail.com

I do realize this :slight_smile: , 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 < hassan.schroeder@gmail.com> wrote:

On Tue, Apr 21, 2009 at 11:11 AM, Brian Wallace <draygen80@gmail.com> > 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 :slight_smile:

--
Hassan Schroeder ------------------------ hassan.schroeder@gmail.com

I do realize this :slight_smile: , 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!

···

On Tue, Apr 21, 2009 at 11:28 AM, Brian Wallace <draygen80@gmail.com> wrote:
--
Hassan Schroeder ------------------------ hassan.schroeder@gmail.com

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

···

On Tue, Apr 21, 2009 at 12:28 PM, Brian Wallace <draygen80@gmail.com> wrote:

I do realize this :slight_smile: , 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

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 < hassan.schroeder@gmail.com> wrote:

On Tue, Apr 21, 2009 at 11:28 AM, Brian Wallace <draygen80@gmail.com> > wrote:
> I do realize this :slight_smile: , 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@gmail.com

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 <tim.pease@gmail.com> wrote:

On Tue, Apr 21, 2009 at 12:28 PM, Brian Wallace <draygen80@gmail.com> > wrote:
> I do realize this :slight_smile: , 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

Look up File.basename and File.dirname

martin

···

On Wed, Apr 22, 2009 at 12:42 AM, Brian Wallace <draygen80@gmail.com> wrote:

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.