# -*- coding: utf-8 -*-

"""livereload.task

Task management for LiveReload Server.

A basic syntax overview::

    from livereload.task import Task

    Task.add('file.css')

    def do_some_thing():
        pass

    Task.add('file.css', do_some_thing)
"""

import os
import glob

IGNORE = [
    '.pyc', '.pyo', '.o',
]


class Task(object):
    tasks = {}
    _modified_times = {}

    @classmethod
    def add(cls, path, func=None):
        cls.tasks[path] = func

    @classmethod
    def watch(cls):
        result = False
        changes = []
        for path in cls.tasks:
            if cls._checking(path):
                result = True
                changes.append(path)
                func = cls.tasks[path]
                if func:
                    func()

        return result and changes

    @classmethod
    def _check_file(cls, path):
        for ext in IGNORE:
            if path.endswith(ext):
                return False

        if not os.path.isfile(path):
            return False

        modified = os.stat(path).st_mtime

        if path not in cls._modified_times:
            cls._modified_times[path] = modified
            return False

        if path in cls._modified_times and \
           cls._modified_times[path] == modified:
            return False

        return True

    @classmethod
    def _checking(cls, path):
        if os.path.isfile(path):
            return cls._check_file(path)

        if os.path.isdir(path):
            result = False
            for root, dirs, files in os.walk(path):
                #: don't watch version control dirs
                if '.git' in dirs:
                    dirs.remove('.git')
                if '.hg' in dirs:
                    dirs.remove('.hg')
                if '.svn' in dirs:
                    dirs.remove('.svn')
                for f in files:
                    path = os.path.join(root, f)
                    result = cls._check_file(path) or result

            return result

        result = False
        for f in glob.glob(path):
            result = cls._check_file(f) or result

        return result

@@ -274,16 +274,31 @@
 ort glob
+%0Aimport logging
 %0A%0AIGNORE
@@ -327,16 +327,23 @@
 ', '.o',
+ '.swp'
 %0A%5D%0A%0A%0Acla
@@ -565,16 +565,17 @@
 es = %5B%5D%0A
+%0A
         
@@ -616,25 +616,26 @@
  if cls.
+is
 _ch
-ecking
+anged
 (path):%0A
@@ -853,27 +853,26 @@
     def 
+is
 _ch
-eck_file
+anged
 (cls, pa
@@ -888,129 +888,184 @@
     
-for ext in IGNORE:%0A            if path.endswith(ext):%0A                return False%0A%0A        if not os.path.isfile(path):%0A
+def is_file_changed(path):%0A            if not os.path.isfile(path):%0A                return False%0A%0A            _, ext = os.path.splitext(path)%0A            if ext in IGNORE:%0A    
     
@@ -1094,16 +1094,20 @@
         
+  
+  
 modified
@@ -1109,16 +1109,20 @@
 ified = 
+int(
 os.stat(
@@ -1135,16 +1135,17 @@
 st_mtime
+)
 %0A%0A      
@@ -1146,24 +1146,28 @@
         
+    
 if path 
 not in c
@@ -1158,20 +1158,16 @@
 if path 
-not 
 in cls._
@@ -1180,17 +1180,22 @@
 ed_times
-:
+ and %5C
 %0A       
@@ -1191,32 +1191,35 @@
 d %5C%0A            
+   
 cls._modified_ti
@@ -1229,16 +1229,17 @@
 %5Bpath%5D =
+=
  modifie
@@ -1239,17 +1239,21 @@
 modified
-%0A
+:%0A   
         
@@ -1248,32 +1248,33 @@
 %0A               
+ 
 return False%0A%0A  
@@ -1276,52 +1276,8 @@
 e%0A%0A 
-       if path in cls._modified_times and %5C%0A
     
@@ -1302,33 +1302,32 @@
 ed_times%5Bpath%5D =
-=
  modified:%0A     
@@ -1311,33 +1311,32 @@
 path%5D = modified
-:
 %0A            ret
@@ -1336,122 +1336,47 @@
     
-return False%0A%0A        return True%0A%0A    @classmethod%0A    def _checking(cls, path):%0A        if os.path.isfile(
+logging.info('file changed: %25s' %25 
 path)
-:
 %0A   
@@ -1395,381 +1395,210 @@
 urn 
-cls._check_file(path)%0A%0A        if os.path.isdir(path):%0A            result = False%0A            for root, dirs, files in os.walk(path):%0A                #: don't watch version control dirs%0A                if '.git' in dirs:%0A                    dirs.remove('.git')%0A                if '.hg' in dirs:%0A                    dirs.remove('.hg')%0A                if '.svn' in dirs:%0A    
+True%0A%0A        def is_folder_changed(path):%0A            for root, dirs, files in os.walk(path):%0A                dirs.remove('.git')%0A                dirs.remove('.hg')%0A                dirs.remove('.svn')%0A
     
@@ -1615,38 +1615,39 @@
   dirs.remove('.
-svn
+cvs
 ')%0A
+%0A
                 
@@ -1735,48 +1735,69 @@
     
-result = cls._check_file(path) or result
+if is_file_changed(path):%0A                        return True
 %0A%0A  
@@ -1813,22 +1813,21 @@
  return 
-result
+False
 %0A%0A      
@@ -1824,39 +1824,55 @@
 se%0A%0A        
-result = False%0A
+def is_glob_changed(path):%0A    
         for 
@@ -1909,55 +1909,268 @@
     
-result = cls._check_file(f) or result%0A%0A
+    if is_file_changed(f):%0A                    return True%0A%0A            return False%0A%0A        if os.path.isfile(path):%0A            return is_file_changed(path)%0A        elif os.path.isdir(path):%0A            return is_folder_changed(path)%0A        else:%0A 
         
 retu
@@ -2165,22 +2165,61 @@
         
+   
 return 
-result
+is_glob_changed(path)%0A        return False
 %0A

change task watch. seems fixed #4