func UpdateJob(id int, body io.ReadCloser) string {
	var uncleanJob newJob
	decoder := json.NewDecoder(body)
	err := decoder.Decode(&uncleanJob)
	if err == nil {
		j := uncleanJob.SingleJob
		ouid, _ := strconv.Atoi(j.OuID)
		var sjob database.Job
		sjob.ID = id
		sjob.JobType = 2
		sjob.AmtcCmd = &j.AmtcCmd
		sjob.AmtcDelay = &j.AmtcDelay
		sjob.OuID = &ouid
		sjob.StartTime = j.StartTime
		sjob.RepeatDays = j.RepeatDays
		sjob.Description = j.Description
		return database.UpdateJob(sjob)
	}
	return "{}"
}
UpdateJob updates a scheduled job in DB
package scheduler
import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"strconv"
	"strings"
	"sync"
	"time"
	"github.com/schnoddelbotz/amtgo/amt"
	"github.com/schnoddelbotz/amtgo/database"
)
type emberJob struct {
	JobType        int      `json:"job_type"`
	AmtcCmd        string   `json:"amtc_cmd"`
	AmtcDelay      float64  `json:"amtc_delay"`
	AmtcHosts      []string `json:"hosts"`
	OuID           string   `json:"ou_id"`
	RepeatInterval *int     `json:"repeat_interval"`
	RepeatDays     *int     `json:"repeat_days"`
	LastStarted    *int     `json:"last_started"`
	LastDone       *int     `json:"last_done"`
	StartTime      int      `json:"start_time"`
	Description    *string  `json:"description"`
}
type newJob struct {
	SingleJob emberJob `json:"job"`
}
var lastStateMap = map[int]amt.Laststate{}
var mutex = &sync.Mutex{}
func ScheduledJobsRunloop(verbose bool) {
	lastRunMinute := -1
	for {
		time.Sleep(30 * time.Second)  
		now := time.Now()
		nowWeekday := now.Weekday() + 1  
		nowMinuteOfDay := now.Hour()*60 + now.Minute()
		if lastRunMinute != nowMinuteOfDay {
			jobs := database.GetScheduledJobs(int(nowWeekday), nowMinuteOfDay)
			for _, job := range jobs {
				ou := database.GetOu(*job.OuID)
				optionset := database.GetOptionset(*ou.OptionsetID)
				optionset.Username = "admin"  
				optionset.Password = getPasswordFromFile(optionset.OptPassfile)
				if optionset.SwUseTLS == 1 && optionset.SwSkipcertchk != 1 && optionset.OptCacertfile != "" {
					optionset.CaCertData = amt.LoadCaCertFile(optionset.OptCacertfile)
				}
				myhosts := database.GetHostsByOu(ou.ID)
				var hostsStringArr []string
				for _, h := range myhosts {
					hostsStringArr = append(hostsStringArr, h.Hostname)
				}
				if verbose {
					log.Printf("Scheduled command: %s, delay: %f, hosts: %s", *job.AmtcCmd, *job.AmtcDelay, hostsStringArr)
				}
				if *job.AmtcCmd == "U" {
					database.InsertNotification(database.NotificationTypePowerOn, fmt.Sprintf("Scheduled power-up %s", ou.Name))
				} else if *job.AmtcCmd == "D" {
					database.InsertNotification(database.NotificationTypePowerOff, fmt.Sprintf("Scheduled power-down %s", ou.Name))
				}
				go amt.SequentialCommand(amt.ShortCommandMap[*job.AmtcCmd], hostsStringArr, optionset, *job.AmtcDelay)
			}
			lastRunMinute = nowMinuteOfDay
		}
	}
}
func CreateJob(body io.ReadCloser) string {
	var uncleanJob newJob
	decoder := json.NewDecoder(body)
	err := decoder.Decode(&uncleanJob)
	if err == nil {
		j := uncleanJob.SingleJob
		ouid, _ := strconv.Atoi(j.OuID)
		switch j.JobType {
		case 1:  
			ou := database.GetOu(ouid)
			optionset := database.GetOptionset(*ou.OptionsetID)
			optionset.Username = "admin"  
			optionset.Password = getPasswordFromFile(optionset.OptPassfile)
			if optionset.SwUseTLS == 1 && optionset.SwSkipcertchk != 1 && optionset.OptCacertfile != "" {
				optionset.CaCertData = amt.LoadCaCertFile(optionset.OptCacertfile)
			}
			hostnames := database.GetHostNamesByID(j.AmtcHosts)
			message := fmt.Sprintf("%s %d hosts in %s", amt.ShortCommandMap[j.AmtcCmd], len(hostnames), ou.Name)
			database.InsertNotification(database.NotificationTypeUser, message)
			go amt.SequentialCommand(amt.ShortCommandMap[j.AmtcCmd], hostnames, optionset, j.AmtcDelay)
			return "{}"
		default:  
			var sjob database.Job
			defaultAmtCmd := "U"
			defaultAmtDelay := 2.5
			defaultOu := 1
			amtOu := &defaultOu
			amtCmd := &defaultAmtCmd
			amtDelay := &defaultAmtDelay
			if j.AmtcCmd != "" {
				amtCmd = &j.AmtcCmd
			}
			if j.AmtcDelay != 0 {
				amtDelay = &j.AmtcDelay
			}
			if ouid != 0 {
				amtOu = &ouid
			}
			sjob.JobType = 2
			sjob.AmtcCmd = amtCmd
			sjob.AmtcDelay = amtDelay
			sjob.OuID = amtOu
			sjob.StartTime = j.StartTime
			sjob.RepeatDays = j.RepeatDays
			sjob.Description = j.Description
			return database.InsertJob(sjob)
		}
	}
	return `{ "error" : "` + err.Error() + `"}`
}