from datetime import datetime
from django.http import HttpRequest, HttpResponseBadRequest
from dimagi.utils.dates import DateSpan
from datetime import datetime

def datespan_in_request(from_param="from", to_param="to", 
                        format_string="%Y-%m-%d", default_days=30, inclusive=True):
    """
    Wraps a request with dates based on url params or defaults and
    Checks date validity.
    """
    
    # this is loosely modeled after example number 4 of decorator
    # usage here: http://www.python.org/dev/peps/pep-0318/
    def get_dates(f):
        def wrapped_func(*args, **kwargs):
            # attempt to find the request object from all the argument
            # values, checking first the args and then the kwargs 
            req = None
            for arg in args:
                if _is_http_request(arg):
                    req = arg
                    break
            if not req:
                for arg in kwargs.values():
                    if _is_http_request(arg):
                        req = arg
                        break
            if req:
                dict = req.POST if req.method == "POST" else req.GET
                def date_or_nothing(param):
                    return datetime.strptime(dict[param], format_string)\
                             if param in dict and dict[param] else None
                try:             
                    startdate = date_or_nothing(from_param)
                    enddate = date_or_nothing(to_param)
                except ValueError, e:
                    return HttpResponseBadRequest(unicode(e))
                if startdate or enddate:
                    req.datespan = DateSpan(startdate, enddate, format_string)
                else:        
                    # default to the last N days
                    req.datespan = DateSpan.since(default_days, format=format_string, inclusive=inclusive)
                    req.datespan.is_default = True
                    
            return f(*args, **kwargs) 
        if hasattr(f, "func_name"):
            wrapped_func.func_name = f.func_name
            # preserve doc strings
            wrapped_func.__doc__ = f.__doc__  
            
            return wrapped_func
        else:
            # this means it wasn't actually a view.  
            return f 
    return get_dates

def _is_http_request(obj):
    return obj and isinstance(obj, HttpRequest)

@@ -126,38 +126,8 @@
 Span
-%0Afrom datetime import datetime
 %0A%0Ade
@@ -254,21 +254,69 @@
 30, 
-inclusive=Tru
+%0A                        inclusive=True, default_function=Non
 e):%0A
@@ -420,24 +420,473 @@
 ty.%0A    %22%22%22%0A
+    # you can pass in a function to say what the default should be, %0A    # if you don't it will pull the value from the last default_days%0A    # in. If you override default_function, default_days is ignored.%0A    if default_function is None:%0A        default_function = lambda: DateSpan.since(default_days, %0A                                                  format=format_string, %0A                                                  inclusive=inclusive)%0A
     %0A    # t
@@ -2237,142 +2237,40 @@
     
-# default to the last N days%0A                    req.datespan = DateSpan.since(default_days, format=format_string, inclusive=inclusive
+req.datespan = default_function(
 )%0A  

add support for passing more complex defaults to datespan decorator