github.com/bcampbell/scrapeomat@v0.0.0-20220820232205-23e64141c89e/cmd/slurpserver/filter.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/bcampbell/scrapeomat/store"
     6  	"net/http"
     7  	"net/url"
     8  	"strconv"
     9  	"time"
    10  )
    11  
    12  // helper to make it easier to use Filter in templates
    13  type Filter store.Filter
    14  
    15  func (filt *Filter) IsPubSet(pubCode string) bool {
    16  	for _, code := range filt.PubCodes {
    17  		if code == pubCode {
    18  			return true
    19  		}
    20  	}
    21  	return false
    22  }
    23  
    24  const yyyymmddLayout = "2006-01-02"
    25  
    26  func (filt *Filter) PubFromString() string {
    27  	if filt.PubFrom.IsZero() {
    28  		return ""
    29  	}
    30  	return filt.PubFrom.Format(yyyymmddLayout)
    31  }
    32  
    33  func (filt *Filter) PubToString() string {
    34  	if filt.PubTo.IsZero() {
    35  		return ""
    36  	}
    37  	return filt.PubTo.Format(yyyymmddLayout)
    38  }
    39  
    40  func (filt *Filter) Params() url.Values {
    41  	v := url.Values{}
    42  	if !filt.PubFrom.IsZero() {
    43  		v.Set("pubfrom", filt.PubFrom.Format(yyyymmddLayout))
    44  	}
    45  	if !filt.PubTo.IsZero() {
    46  		v.Set("pubto", filt.PubTo.Format(yyyymmddLayout))
    47  	}
    48  	if !filt.AddedFrom.IsZero() {
    49  		v.Set("addedfrom", filt.PubFrom.Format(yyyymmddLayout))
    50  	}
    51  	if !filt.AddedTo.IsZero() {
    52  		v.Set("addedto", filt.PubTo.Format(yyyymmddLayout))
    53  	}
    54  
    55  	if filt.SinceID != 0 {
    56  		v.Set("since_id", strconv.Itoa(filt.SinceID))
    57  	}
    58  	if filt.Count != 0 {
    59  		v.Set("count", strconv.Itoa(filt.Count))
    60  	}
    61  
    62  	for _, pubCode := range filt.PubCodes {
    63  		v.Add("pub", pubCode)
    64  	}
    65  	for _, pubCode := range filt.XPubCodes {
    66  		v.Add("xpub", pubCode)
    67  	}
    68  
    69  	// v.Encode() == "name=Ava&friend=Jess&friend=Sarah&friend=Zoe"
    70  
    71  	return v
    72  }
    73  
    74  func parseTime(in string) (time.Time, error) {
    75  
    76  	t, err := time.ParseInLocation(time.RFC3339, in, time.UTC)
    77  	if err == nil {
    78  		return t, nil
    79  	}
    80  
    81  	// short form - assumes you want utc days rather than local days...
    82  	t, err = time.ParseInLocation(yyyymmddLayout, in, time.UTC)
    83  	if err != nil {
    84  		return time.Time{}, fmt.Errorf("invalid date/time format")
    85  	}
    86  
    87  	return t, nil
    88  
    89  }
    90  
    91  func getFilter(r *http.Request) (*store.Filter, error) {
    92  	maxCount := 20000
    93  
    94  	filt := &store.Filter{}
    95  
    96  	// deprecated!
    97  	if r.FormValue("from") != "" {
    98  		t, err := parseTime(r.FormValue("from"))
    99  		if err != nil {
   100  			return nil, fmt.Errorf("bad 'from' param")
   101  		}
   102  
   103  		filt.PubFrom = t
   104  	}
   105  
   106  	// deprecated!
   107  	if r.FormValue("to") != "" {
   108  		t, err := parseTime(r.FormValue("to"))
   109  		if err != nil {
   110  			return nil, fmt.Errorf("bad 'to' param")
   111  		}
   112  		t = t.AddDate(0, 0, 1) // add one day
   113  		filt.PubTo = t
   114  	}
   115  
   116  	// TODO: addedfrom/addedto???
   117  
   118  	if r.FormValue("pubfrom") != "" {
   119  		t, err := parseTime(r.FormValue("pubfrom"))
   120  		if err != nil {
   121  			return nil, fmt.Errorf("bad 'pubfrom' param")
   122  		}
   123  
   124  		filt.PubFrom = t
   125  	}
   126  	if r.FormValue("pubto") != "" {
   127  		t, err := parseTime(r.FormValue("pubto"))
   128  		if err != nil {
   129  			return nil, fmt.Errorf("bad 'pubto' param")
   130  		}
   131  
   132  		filt.PubTo = t
   133  	}
   134  
   135  	if r.FormValue("since_id") != "" {
   136  		sinceID, err := strconv.Atoi(r.FormValue("since_id"))
   137  		if err != nil {
   138  			return nil, fmt.Errorf("bad 'since_id' param")
   139  		}
   140  		if sinceID > 0 {
   141  			filt.SinceID = sinceID
   142  		}
   143  	}
   144  
   145  	if r.FormValue("count") != "" {
   146  		cnt, err := strconv.Atoi(r.FormValue("count"))
   147  		if err != nil {
   148  			return nil, fmt.Errorf("bad 'count' param")
   149  		}
   150  		filt.Count = cnt
   151  	} else {
   152  		// default to max
   153  		filt.Count = maxCount
   154  	}
   155  
   156  	// enforce max count
   157  	if filt.Count > maxCount {
   158  		return nil, fmt.Errorf("'count' too high (max %d)", maxCount)
   159  	}
   160  
   161  	// publication codes?
   162  	if pubs, got := r.Form["pub"]; got {
   163  		filt.PubCodes = pubs
   164  	}
   165  
   166  	// publication codes to exclude?
   167  	if xpubs, got := r.Form["xpub"]; got {
   168  		filt.XPubCodes = xpubs
   169  	}
   170  
   171  	return filt, nil
   172  }