M README.md => README.md +7 -0
@@ 123,6 123,13 @@ liner:
[[ $(qcal -cron 15 2>/dev/null) ]] && notify-send "Next Appointment:" "\n $(qcal -cron 15)" || true
+### External password command
+
+Instead of putting your password in the config file you can specify an
+external command to resolve your password. Put a line like this in your
+calendar config and leave the "Password" field empty:
+
+ "PasswordCommand":"rbw get email-provider"
## About
M defines.go => defines.go +5 -4
@@ 24,7 24,7 @@ var endDateUTC string
var summary string
var toFile bool
var elements []Event
-var qcalversion string = "0.8.9"
+var qcalversion string = "0.9.0"
var colorBlock string = "|"
var currentDot string = "•"
@@ 57,9 57,10 @@ const (
type configStruct struct {
Calendars []struct {
- Url string
- Username string
- Password string
+ Url string
+ Username string
+ Password string
+ PasswordCmd string
}
Timezone string
DefaultNumDays int
M main.go => main.go +16 -1
@@ 8,6 8,8 @@ import (
"io/ioutil"
"log"
"net/http"
+ "os"
+ "os/exec"
"sort"
"strconv"
"strings"
@@ 36,7 38,20 @@ func fetchCalData(calNo int, wg *sync.WaitGroup) {
req, _ := http.NewRequest(reqType, config.Calendars[calNo].Url, strings.NewReader(xmlBody))
if config.Calendars[calNo].Username != "" {
- req.SetBasicAuth(config.Calendars[calNo].Username, config.Calendars[calNo].Password)
+ var pw string
+ if config.Calendars[calNo].PasswordCmd == "" {
+ pw = config.Calendars[calNo].Password
+ } else {
+ cmd := exec.Command("sh", "-c", config.Calendars[calNo].PasswordCmd)
+ cmd.Stdin = os.Stdin
+ output, err := cmd.Output()
+ if err != nil {
+ log.Fatal(err)
+ }
+ pw = strings.TrimSpace(string(output))
+ }
+
+ req.SetBasicAuth(config.Calendars[calNo].Username, pw)
req.Header.Add("Depth", "1") // needed for SabreDAV
req.Header.Add("Prefer", "return-minimal")
req.Header.Add("Content-Type", "application/xml; charset=utf-8")