Пример #1
0
func pipeLogs(r io.Reader, prefix string) {
	logger := util.GetLogger()
	scanner := bufio.NewScanner(r)
	for scanner.Scan() {
		logger.Info("%s %s", prefix, scanner.Text())
	}
}
Пример #2
0
func (pt1 *Pt1Recorder) checkPrograms() {
	logger := util.GetLogger()
	for {
		var channels []*tv.TvChannel
		var err error
		for channels == nil || len(channels) == 0 {
			channels, err = api.GetTvChannels()
			if err != nil {
				logger.Error("[Pt1Recorder] Failed to get channels: %v", err)
				time.Sleep(Pt1Config.FetchInterval)
			} else {
				logger.Info("[Pt1Recorder] Got %d channels. Start to check programs...", len(channels))
			}
		}

		for _, ch := range channels {
			upcomming := pt1.recorder.Upcomming()
			now := time.Now()
			if upcomming.IsZero() || now.Add(pt1.pt1Config.ProgramCheckDuration*3).Before(upcomming) {
				// ok to launch recpt1 and dummy recording
				err = pt1.updatePrograms(ch)
				if err != nil {
					logger.Warn("[Pt1Recorder] Could not update the channel: %v - %s:%s", err, ch.Cid, ch.Name)
				} else {
					logger.Info("[Pt1Recorder] Updated channel: %s", ch.Name)
				}
			} else {
				logger.Warn("[Pt1Recorder] Could not use pt1 device so skipped to check channels: %s", ch.Name)
			}
		}
		time.Sleep(pt1.pt1Config.ProgramCheckInterval)
	}
}
Пример #3
0
func NewRecordCtrl(rec Record) *RecordCtrl {
	return &RecordCtrl{
		record: rec,
		state:  RSWaiting,
		stopCh: make(chan bool, 1),
		logger: util.GetLogger(),
	}
}
Пример #4
0
func (r *Pt1Record) Kill() {
	// send KILL
	if r.cmd != nil {
		util.GetLogger().Info("[recpt1][%s] Canceling the process.", r.Key())
		r.signaled = true
		exec.Command("kill", "-9", strconv.Itoa(r.cmd.Process.Pid)).Run()
	}
}
Пример #5
0
// Create a new Recorder instance.
// receiver should be a channel to register the record
func NewRecorder(receiver <-chan []Record) *Recorder {
	return &Recorder{
		receiver:   receiver,
		recorder:   make(chan *RecordResult, 128),
		controls:   make(map[string]*RecordCtrl),
		shouldStop: false,
		logger:     util.GetLogger(),
	}
}
Пример #6
0
func (pt1 *Pt1Recorder) updatePrograms(ch *tv.TvChannel) error {
	var stdout bytes.Buffer
	var stderr bytes.Buffer
	logger := util.GetLogger()
	d := int(pt1.pt1Config.ProgramCheckDuration.Seconds())
	tspath := filepath.Join(
		pt1.pt1Config.StoragePath,
		fmt.Sprintf(".updateProgram.%s.ts", ch.Cid),
	)
	jsonpath := filepath.Join(
		pt1.pt1Config.StoragePath,
		fmt.Sprintf(".updateProgram.%s.json", ch.Cid),
	)

	// execute recpt1
	args := []string{"--b25", "--strip", ch.Cid, fmt.Sprintf("%d", d), tspath}
	recpt1 := exec.Command(pt1.pt1Config.Recpt1Path, args...)
	recpt1.Stdout = &stdout
	recpt1.Stderr = &stderr
	err := recpt1.Run()
	if err != nil {
		logger.Warn("[Pt1Recorder] Could not execute recpt1: %v", err)
		logger.Warn("[CMD] %s %s", pt1.pt1Config.Recpt1Path, strings.Join(args, " "))
		logger.Warn("[STDOUT]: %s", stdout.String())
		logger.Warn("[STDERR]: %s", stderr.String())
		return err
	}
	logger.Debug("[Pt1Recorder] Generated %s for updating programs.", tspath)
	// execute epgdump to generate json
	args = []string{"json", tspath, jsonpath}
	epgdump := exec.Command(pt1.pt1Config.EpgdumpPath, args...)
	err = epgdump.Run()
	if err != nil {
		logger.Warn("[Pt1Recorder] Could not execute epgdump: %v", err)
		return err
	}
	logger.Debug("[Pt1Recorder] Generated %s for updating programs.", jsonpath)
	// upload json data to server
	jsondata, err := ioutil.ReadFile(jsonpath)
	if err != nil {
		logger.Warn("[Pt1Recorder] Could not read the generated jsonfile on %s: %v", jsonpath, err)
		return err
	}
	resp, err := api.UploadPrograms(ch.Cid, bytes.NewBuffer(jsondata))
	if err != nil {
		logger.Warn("[Pt1Recorder] Could not post the jsondata to the endpoint: %v", err)
		return err
	} else {
		logger.Info(
			"[Pt1Recorder] Uploaded %d programs, %d parse errors, %d database errors",
			len(resp["ids"]),
			len(resp["parse_errors"]),
			len(resp["database_errors"]),
		)
	}
	return nil
}
Пример #7
0
func (r *Pt1Record) Stop() error {
	// send TERM
	if r.IsRunning() {
		util.GetLogger().Info("[recpt1][%s] Stopping the process.", r.Key())
		r.signaled = true
		err := exec.Command("kill", strconv.Itoa(r.cmd.Process.Pid)).Run()
		return err
	}
	return nil
}
Пример #8
0
func (r *Pt1Record) Start() error {
	var err error
	logger := util.GetLogger()

	// make sure the directory exists
	if err = os.MkdirAll(r.DirectoryPath(), 0755); err != nil {
		return err
	}

	r.filepath = r.resolveFilePath()
	r.cmd = NewRecCommand(r.Recpt1Path, r.tvrecord.Cid, r.tvrecord.Sid, r.filepath)
	stdout, _ := r.cmd.StdoutPipe()
	stderr, _ := r.cmd.StderrPipe()
	err = r.cmd.Start()
	if err != nil {
		return err
	}

	logger.Info("[recpt1][%s] Started.", r.Key())

	go pipeLogs(stderr, fmt.Sprintf("[recpt1][%s][stderr]", r.Key()))
	go pipeLogs(stdout, fmt.Sprintf("[recpt1][%s][stdout]", r.Key()))
	go func() {
		err := r.cmd.Wait()
		if err != nil {
			// failed.
			if r.signaled {
				logger.Info("[recpt1][%s] Stopped by signal: %v", r.Key(), err)
			} else {
				logger.Info("[recpt1][%s] Failed: %v", r.Key(), err)
			}
		} else {
			if r.cmd.ProcessState == nil {
				// could not started.

			} else {
				if r.cmd.ProcessState.Success() {
					logger.Info("[recpt1][%s] Completed successfully.", r.Key())
				} else {
					// failed.
					if r.signaled {
						logger.Info("[recpt1][%s] Stopped by signal.", r.Key())
					} else {
						logger.Info("[recpt1][%s] Failed.", r.Key())
					}
				}
			}
		}
		r.cmd = nil
		r.signaled = false
	}()
	return nil
}
Пример #9
0
func (pt1 *Pt1Recorder) subscribe() {
	logger := util.GetLogger()
	for {
		records, err := api.GetTvRecords()
		if err != nil {
			logger.Error("[Pt1Recorder] Failed to get records: %v", err)
		} else {
			logger.Debug("[Pt1Recorder] Got %d records from the server.", len(records))
			list := make([]tv.Record, len(records))
			for i, v := range records {
				list[i] = NewPt1Record(v, pt1.pt1Config)
			}
			pt1.receiver <- list
		}
		time.Sleep(pt1.pt1Config.FetchInterval)
	}
}