Ejemplo n.º 1
0
func foscamStatus(w http.ResponseWriter, r *http.Request, m map[string]interface{}) {

	htmlfrag.SetNocacheHeaders(w)
	w.Header().Set("Content-Type", "text/html; charset=utf-8")

	logRetrieve(w, r)

	cgiRes := makeRequest(w, r, path_get_alarm)

	psXml := stringspb.IndentedDump(cgiRes)
	dis := strings.Trim(psXml, "{}")
	dis = strings.Replace(dis, "\t", "", -1)
	dis = strings.Replace(dis, " ", "", -1)
	dis = strings.Replace(dis, "\"", "", -1)
	dis = strings.Replace(dis, "\n", " ", -1)
	dis = strings.Replace(dis, "Area0", "\nArea0", -1)
	dis = strings.Replace(dis, "Schedule0", "\nSchedule0", -1)
	dis = strings.Replace(dis, "Log0", "\nLog0", -1)
	wpf(w, "<pre style='font-size:10px;line-height:11px;'>%v</pre>", dis)

	if cgiRes.IsEnable == "0" {
		wpf(w, "Status <b>DISabled</b><br><br>\n")
	} else {
		wpf(w, "Status <b>ENabled</b><br><br>\n")
	}

	imageRetrieve(w, r)

}
Ejemplo n.º 2
0
func foscamWatch(w http.ResponseWriter, r *http.Request, m map[string]interface{}) {

	htmlfrag.SetNocacheHeaders(w)
	w.Header().Set("Content-Type", "text/html; charset=utf-8")

	wpf(w, tplx.ExecTplHelper(tplx.Head, map[string]interface{}{"HtmlTitle": "Foscam live watch"}))

	/*

		There is no way to access a real video stream.
		Thus we use this suggestion: http://foscam.us/forum/post43654.html#p43654

	*/
	str := `<img 
	width='640' 
	src="http://` + dns_cam + `/CGIProxy.fcgi?cmd=snapPicture2&usr=visitor&pwd=visitor&t=" 
	onload='setTimeout(function() {src = src.substring(0, (src.lastIndexOf("t=")+2))+(new Date()).getTime()}, 1000)' 
	onerror='setTimeout(function() {src = src.substring(0, (src.lastIndexOf("t=")+2))+(new Date()).getTime()}, 5000)' 
	alt='' />`
	w.Write([]byte(str))

	w.Write([]byte(tplx.Foot))

}
Ejemplo n.º 3
0
func foscamToggle(w http.ResponseWriter, r *http.Request, m map[string]interface{}) {

	htmlfrag.SetNocacheHeaders(w)
	w.Header().Set("Content-Type", "text/html; charset=utf-8")

	ssecs := r.FormValue("sleep")
	if ssecs != "" {
		secs := util.Stoi(ssecs)
		wpf(w, "sleeping %v secs ... <br><br>\n", secs)
		time.Sleep(time.Duration(secs) * time.Second)
	}

	prevStat := makeRequest(w, r, path_get_alarm)

	wpf(w, "||%s||<br>\n", prevStat.IsEnable)
	if strings.TrimSpace(prevStat.IsEnable) == "0" {
		prevStat.IsEnable = "1"
	} else {
		prevStat.IsEnable = "0"
	}
	prevStat.Area0 = "255"
	prevStat.Area1 = "255"
	prevStat.Area2 = "255"
	prevStat.Area3 = "255"
	prevStat.Area4 = "255"
	prevStat.Area5 = "255"
	prevStat.Area6 = "255"
	prevStat.Area7 = "255"
	prevStat.Area8 = "255"
	prevStat.Area9 = "255"

	// ugly: XML dump to query string
	s2 := spf("%+v", prevStat)
	s2 = strings.Trim(s2, "{}")
	s2 = strings.Replace(s2, ":", "=", -1)
	s2 = strings.Replace(s2, " ", "&", -1)

	// even worse: we have to lower the case again
	pairs := strings.Split(s2, "&")
	recombined := ""
	for i, v := range pairs {
		fchar := v[:1]
		fchar = strings.ToLower(fchar)
		recombined += fchar + v[1:]
		if i < len(pairs)-1 {
			recombined += "&"
		}
	}

	wpf(w, "<pre>")
	// disS2 := stringspb.Breaker(s2, 50)
	// for _, v := range disS2 {
	// 	wpf(w, "%v\n", v)
	// }
	disRecombined := stringspb.Breaker(recombined, 50)
	for _, v := range disRecombined {
		wpf(w, "%v\n", v)
	}
	wpf(w, "</pre>")
	// wpf(w, "<pre>%v</pre>\n", recombined)

	toggleRes := makeRequest(w, r, path_set_alarm+"&"+recombined)
	if toggleRes.Result == "0" {
		wpf(w, "<br>end foscam toggle - success<br>\n")
		if prevStat.IsEnable == "0" {
			wpf(w, "<b>DISabled</b><br>\n")
		} else {
			wpf(w, "<b>ENabled</b><br>\n")
		}
	}

}
Ejemplo n.º 4
0
// We cannot use http.FileServer(http.Dir("./css/")
// to dispatch our dsfs files.
// We need the appengine context to initialize dsfs.
// Thus we have to re-implement a serveFile method:
func FsiFileServer(w http.ResponseWriter, r *http.Request, opt Options) {

	r.Header.Set("X-Custom-Header-Counter", "nocounter")

	lg, b1 := loghttp.BuffLoggerUniversal(w, r)

	fclose := func() {
		// Only upon error.
		// If everything is fine, we reset fclose at the end.
		w.Write(b1.Bytes())
	}
	defer fclose()

	wpf(b1, tplx.ExecTplHelper(tplx.Head, map[string]interface{}{"HtmlTitle": "Half-Static-File-Server"}))
	wpf(b1, "<pre>")

	err := r.ParseForm()
	if err != nil {
		wpf(b1, "err parsing request (ParseForm)%v", err)
	}

	p := r.URL.Path

	if strings.HasPrefix(p, opt.Prefix) {
		// p = p[len(prefix):]
		p = strings.TrimPrefix(p, opt.Prefix)
	} else {
		wpf(b1, "route must start with prefix %v - but is %v", opt.Prefix, p)
	}

	if strings.HasPrefix(p, "/") {
		p = p[1:]
	}
	wpf(b1, "effective path = %q", p)

	// fullP := path.Join(docRootDataStore, p)
	fullP := p

	f, err := opt.FS.Open(fullP)
	if err != nil {
		wpf(b1, "err opening file %v - %v", fullP, err)
		return
	}
	defer f.Close()

	inf, err := f.Stat()
	if err != nil {
		wpf(b1, "err opening fileinfo %v - %v", fullP, err)
		return
	}

	if inf.IsDir() {

		wpf(b1, "%v is a directory - trying index.html...", fullP)

		fullP += "/index.html"

		fIndex, err := opt.FS.Open(fullP)
		if err == nil {
			defer fIndex.Close()
			inf, err = fIndex.Stat()
			if err != nil {
				wpf(b1, "err opening index fileinfo %v - %v", fullP, err)
				return
			}

			f = fIndex
		} else {

			wpf(b1, "err opening index file %v - %v", fullP, err)

			if r.FormValue("fmt") == "html" {
				dirListHtml(w, r, f)
			} else {
				dirListJson(w, r, f)
			}

			b1 = new(bytes.Buffer) // success => reset the message log => dumps an empty buffer
			return
		}

	}

	wpf(b1, "opened file %v - %v -  %v", f.Name(), inf.Size(), err)

	bts1, err := ioutil.ReadAll(f)
	if err != nil {
		wpf(b1, "err with ReadAll %v - %v", fullP, err)
		return
	}

	ext := path.Ext(fullP)
	ext = strings.ToLower(ext)
	if ext == ".snappy" {
		btsDec, err := snappy.Decode(nil, bts1)
		if err != nil {
			wpf(b1, "err decoding snappy: "+err.Error())
		} else {
			lg("decoded from %vkB to %vkB", len(bts1)/1024, len(btsDec)/1024)
			bts1 = btsDec
		}
		fullP = strings.TrimSuffix(fullP, path.Ext(fullP))
		ext = path.Ext(fullP)
		ext = strings.ToLower(ext)
		lg("new extension is %v", ext)
	}

	tp := mime.TypeByExtension(ext)

	w.Header().Set("Content-Type", tp)

	//
	// caching
	// either explicitly discourage
	// or     explicitly  encourage
	if false ||
		ext == ".css" || ext == ".js" ||
		ext == "css" || ext == "js" ||
		ext == ".jpg" || ext == ".gif" ||
		ext == "jpg" || ext == "gif" ||
		false {

		if strings.Contains(fullP, "tamper-monkey") {
			htmlfrag.SetNocacheHeaders(w)
		} else {
			htmlfrag.CacheHeaders(w)
		}
	} else {
		htmlfrag.SetNocacheHeaders(w)
	}

	for k, v := range opt.Replacements {
		bts1 = bytes.Replace(bts1, []byte(k), v, -1)
	}
	if opt.Cutout {
		sep := []byte("<span id='CUTOUT'></span>")
		spl := bytes.Split(bts1, sep)
		if len(spl) > 1 {
			bts2 := []byte{}
			for i, part := range spl {
				if i%2 == 0 {
					bts2 = append(bts2, part...)
				}
			}
			bts1 = bts2
		}
	}

	w.Write(bts1)

	b1 = new(bytes.Buffer) // success => reset the message log => dumps an empty buffer

}
Ejemplo n.º 5
0
/*

https://developers.coinbase.com/docs/merchants/callbacks


id				Order number used to uniquely identify an order on Coinbase
completed_at	ISO 8601 timestamp when the order completed
status			[completed, mispaid, expired]
event			[completed, mispayment]. If mispayment => check key mispayment_id. Distinction from status ...
total_btc		Total amount of the order in ‘satoshi’ (1 BTC = 100,000,000 Satoshi). Note the use of the word ‘cents’ in the callback really means satoshi in this context. The btc amount will be calculated at the current exchange rate at the time the order is placed (current to within 15 minutes).
total_native	Units of local currency. 1 unit = 100 cents. Equal to the price from creating the button.
total_payout	Units of local currency deposited using instant payout.
custom			Custom parameter from data-custom attribute of button. Usually an Order, User, or Product ID
receive_address	Bitcoin address associated with this order. This is where the payment was sent.
button			Button details. ID matches the data-code parameter in your embedded HTML code.
transaction		Hash and number of confirmations of underlying transaction.
				Number of confirmations typically zero at the time of the first callback.
customer		Customer information from order form. Can include email xor shipping address.
refund_address	Experimental parameter that is subject to change.


*/
func confirmPay(w http.ResponseWriter, r *http.Request, m map[string]interface{}) {

	lg, b := loghttp.BuffLoggerUniversal(w, r)
	closureOverBuf := func(bUnused *bytes.Buffer) {
		// loghttp.Pf(w, r, b.String())
	}
	defer closureOverBuf(b) // the argument is ignored,
	r.Header.Set("X-Custom-Header-Counter", "nocounter")

	htmlfrag.SetNocacheHeaders(w)

	//____________________________________________________________________

	bts, err := ioutil.ReadAll(r.Body)
	if err != nil {
		lg("cannot read resp body: %v", err)
		return
	}
	defer r.Body.Close()

	// lg("bytes are -%s-", stringspb.ToLen(string(bts), 20))

	if len(bts) < 1 {
		lg("lo empty post body")
		w.WriteHeader(http.StatusOK)
		b = new(bytes.Buffer)
		return
	}

	var mp map[string]interface{}
	err = json.Unmarshal(bts, &mp)
	lg(err)

	mpPayout := submap(mp, "payout", lg)
	if len(mpPayout) > 0 {
		lg("lo " + stringspb.IndentedDump(mpPayout))
	}
	mpAddress := submap(mp, "address", lg)
	if len(mpAddress) > 0 {
		lg("lo " + stringspb.IndentedDump(mpAddress))
	}

	var cents, BTC float64
	var status string

	mpOrder := submap(mp, "order", lg)
	if len(mpOrder) < 1 {
		w.WriteHeader(http.StatusLengthRequired)
		lg("mpOrder not present %v", status)
		return
	} else {
		lg("lo " + stringspb.IndentedDump(mpOrder))

		mpBTC := submap(mpOrder, "total_btc", lg)
		// lg("lo " + stringspb.IndentedDump(mpBTC))

		if icents, ok := mpBTC["cents"]; ok {
			cents, ok = icents.(float64)
			if !ok {
				lg(" mpBTC[cents] is of unexpected type %T ", mpBTC["cents"])
			}
			BTC = cents / (1000 * 1000 * 100)

		} else {
			lg(" mpBTC[cents] not present")
		}
		lg("received %18.2f satoshi, %2.9v BTC ", cents, BTC)

		if _, ok := mpOrder["status"]; ok {
			status, ok = mpOrder["status"].(string)
			if !ok {
				lg(" mpOrder[status] is of unexpected type %T ", mpOrder["status"])
			}
		}

		lg("status    %v  ", status)
		lg("custom   %#v  ", mpOrder["custom"])
		lg("customer %#v - mostly empty", mpOrder["customer"])

		var values url.Values
		if _, ok := mpOrder["custom"]; ok {
			if mpOrder["custom"] == "123456789" {
				lg("test request recognized")
				values = url.Values{}
				values.Add("uID", "testUser123")
				values.Add("productID", "/member/somearticle")
			} else {
				var err error
				values, err = url.ParseQuery(mpOrder["custom"].(string))
				lg(err)
				if err != nil {
					w.WriteHeader(http.StatusLengthRequired)
					lg("unsatisfactory query in custom string %v", mpOrder["custom"])
					return
				}
			}
		} else {
			w.WriteHeader(http.StatusLengthRequired)
			lg("custom string not present")
			return
		}

		//  save
		if status == "completed" {
			lg("status 'completed'")
			blob := dsu.WrapBlob{
				VByte: stringspb.IndentedDumpBytes(mpOrder),
			}
			blob.Name = values.Get("uID")
			blob.Category = "invoice"
			blob.S = values.Get("productID")
			blob.Desc = status
			blob.F = BTC
			blob.I = int(time.Now().Unix())

			// blob.VVByte, _ = conv.String_to_VVByte(string(blob.VByte)) // just to make it readable

			newKey, err := dsu.BufPut(appengine.NewContext(r), blob, blob.Name+blob.S)
			lg("key is %v", newKey)
			lg(err)

			retrieveAgain, err := dsu.BufGet(appengine.NewContext(r), "dsu.WrapBlob__"+blob.Name+blob.S)
			lg(err)
			lg("retrieved %v %v %v", retrieveAgain.Name, retrieveAgain.Desc, retrieveAgain.F)

		} else {
			w.WriteHeader(http.StatusLengthRequired)
			lg("unsatisfactory status %v", status)
			return
		}

	}
	w.WriteHeader(http.StatusOK)
	b = new(bytes.Buffer)

}