Giter Site home page Giter Site logo

inotify.cr's Introduction

inotify

Inotify bindings for Crystal language.

GitHub release Travis GitHub license

Installation

Add this to your application's shard.yml:

dependencies:
  inotify:
    github: petoem/inotify.cr
    version: 1.0.1

Usage

require "inotify"

# To watch a file or directory ...
watcher = Inotify.watch "/path/to/file.txt" do |event|
  # your awesome logic
end

# ... for 10 seconds.
sleep 10.seconds
watcher.close

Note: You have to run something in the main fiber or else your program will exit.

More documentation can be found here.

Development

To enable logging to STDOUT using environment variables, follow the instructions in the api docs. Use log source inotify and severity level DEBUG.

Contributing

  1. Fork it!
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors

  • petoem Michael Petö - creator, maintainer

inotify.cr's People

Contributors

kimburgess avatar petoem avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Forkers

bararchy j8r bit4bit

inotify.cr's Issues

undefined method 'watch'

Example code in readme produce below error

crystal build -o /Users/weaming/src/project-name/bin/test src/test.cr
Error target test failed to compile:
Error in src/test.cr:3: undefined method 'watch' for Inotify:Module

watcher = Inotify.watch "./nginx.log" do |event|
                  ^~~~~

File::Stat ⇒ File::Info for crystal 0.25

Hi,

In crystal 0.25, "File.stat was renamed to File.info and a more portable API was implemented".
Here the only change to be compatible with 0.25 is in fallback.cr, 3rd line (File::Stat ⇒ File::Info). But it will break older versions…

Dir class has no foreach() in Crystal 0.24+

Hi,

Dir has no foreach() method anymore (at least in Crystal 0.24), and the check for "." and ".." may be removed if using each_child.
Only occurrence is here: src/inotify/watcher.cr line 103

I don't know if you want to keep backward compatibility or whatever, but would be nice to fix this, otherwise it works well :)

Thanks

Can't infer the type of instance variable '@event_callbacks' of Inotify::Watcher

Error target log-watcher failed to compile:
Error in lib/inotify/src/inotify/watcher.cr:21: Can't infer the type of instance variable '@event_callbacks' of Inotify::Watcher

The type of a instance variable, if not declared explicitly with
`@event_callbacks : Type`, is inferred from assignments to it across
the whole program.

The assignments must look like this:

  1. `@event_callbacks = 1` (or other literals), inferred to the literal's type
  2. `@event_callbacks = Type.new`, type is inferred to be Type
  3. `@event_callbacks = Type.method`, where `method` has a return type
     annotation, type is inferred from it
  4. `@event_callbacks = arg`, with 'arg' being a method argument with a
     type restriction 'Type', type is inferred to be Type
  5. `@event_callbacks = arg`, with 'arg' being a method argument with a
     default value, type is inferred using rules 1, 2 and 3 from it
  6. `@event_callbacks = uninitialized Type`, type is inferred to be Type
  7. `@event_callbacks = LibSome.func`, and `LibSome` is a `lib`, type
     is inferred from that fun.
  8. `LibSome.func(out @event_callbacks)`, and `LibSome` is a `lib`, type
     is inferred from that fun argument.

Other assignments have no effect on its type.

Can't infer the type of instance variable '@event_callbacks' of Inotify::Watcher

    @event_callbacks = [] of Proc(Event, Nil)
    ^~~~~~~~~~~~~~~~

Add method yielding no event values

I'm the author of https://github.com/j8r/tail
To tail a file, I essentially do:

file = File.new path
Inotify::Watcher.new file.path do |event|
  if !(content = file.gets_to_end).empty?
    puts content
  end
end

Which is not the most efficient for tailing only one file.
I see also there is a @io.read(slice) on the lurk method, would it be possible to have a method yielding the appended data?

Proposition

  • make the initialize of Watcher and Fallback not accept a block.
  • create methods that yield an event (with the appended data?), another one that yield only the appended data and/or one that yields no values. IOs and fds can be created when calling them.
  • A method could stop the watch, and closing any IOs, and one creating them again for watching.
  • the above propositions means overhauling the API. Watcher and Fallback can even become structs.

better way to "debounce" inotify events?

Thanks for making such a useful lib!

I would like to debounce events so that I don't get notified unless no events have happened for at least a second. I came up with the following but it seems hackish, do you have an idea of a better way to do it? In the end, would like to use the code to keep directory synced up.

require "inotify"


class Sync
  
  def initialize
    @events = [] of Inotify::Event
    @t = Time.now
    watch()
  end
  
  def push_event(event)
    @events.push(event)
    @t = Time.now
  end
  
  def watch
    Inotify::Watcher.new(".") do |event|
      push_event(event)
    end
  end

  def process_event(event)
    pp event
    type = event.event_type
    if event.event_type == Inotify::EventType::MOVE
      if event.mask == LibInotify::IN_MOVED_FROM
        type = "DELETED"
      elsif event.mask == LibInotify::IN_MOVED_TO
        type = "CREATE"
      end
    end
    puts [event.name, type].join(" => ")
  end
  
  def do_loop
    loop do
      sleep 1
      if @events.size > 0 && Time.now - @t > 1.second
        seen = {} of String => Bool
        while e = @events.shift?
          if ! seen["#{e.event_type}-#{e.name}"]?
            process_event(e)
            seen["#{e.event_type}-#{e.name}"] = true
          end
#          pp e
        end
      else
        puts "PING"
      end
    end
  end
end

s = Sync.new
s.do_loop()

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.