SHARE
TWEET

Untitled

a guest Jun 25th, 2019 140 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package main
  2.  
  3. import (
  4.     "flag"
  5.     "fmt"
  6.     "log"
  7.     "os"
  8.     "os/exec"
  9.     "time"
  10.  
  11.     "github.com/BurntSushi/xgb"
  12.     "github.com/BurntSushi/xgb/screensaver"
  13.     "github.com/BurntSushi/xgb/xproto"
  14.     "github.com/esiqveland/notify"
  15.     "github.com/godbus/dbus"
  16.     "github.com/google/shlex"
  17. )
  18.  
  19. func getIdleTime(con *xgb.Conn, drawable xproto.Drawable) (uint32, error) {
  20.  
  21.     request := screensaver.QueryInfo(con, drawable)
  22.     qinfo, err := request.Reply()
  23.     if err != nil {
  24.         return 0, err
  25.     }
  26.     return qinfo.MsSinceUserInput, nil
  27. }
  28.  
  29. func isIdle(con *xgb.Conn, drawable xproto.Drawable, maxidletime uint32) bool {
  30.     idletime, _ := getIdleTime(con, drawable)
  31.     log.Println("Idle time", idletime)
  32.     return idletime > maxidletime
  33. }
  34.  
  35. func waitForChange(conn *dbus.Conn, devicepath string) bool {
  36.     matches := []dbus.MatchOption{dbus.WithMatchOption("path", devicepath),
  37.         dbus.WithMatchInterface("org.freedesktop.DBus.Properties"),
  38.         dbus.WithMatchMember("PropertiesChanged"),
  39.         dbus.WithMatchOption("arg0", "org.bluez.Device1")}
  40.     conn.AddMatchSignal(matches...)
  41.  
  42.     c := make(chan *dbus.Signal, 10)
  43.     conn.Signal(c)
  44.     for v := range c {
  45.         var changes map[string]dbus.Variant
  46.         changes = v.Body[1].(map[string]dbus.Variant)
  47.         if val, ok := changes["Connected"]; ok {
  48.             isconnected := val.Value().(bool)
  49.             log.Println("Isconnected", isconnected)
  50.             conn.RemoveMatchSignal(matches...)
  51.             return isconnected
  52.         }
  53.     }
  54.     return false
  55. }
  56.  
  57. func lock(app []string) {
  58.     cmd := exec.Command(app[0], app[1:]...)
  59.     err := cmd.Start()
  60.     log.Println(err)
  61.     err = cmd.Wait()
  62.     log.Println(err)
  63. }
  64.  
  65. func tryConnect(conn *dbus.Conn, devicepath string) bool {
  66.     var connected dbus.Variant
  67.     obj := conn.Object("org.bluez", dbus.ObjectPath(devicepath))
  68.     connected, _ = obj.GetProperty("org.bluez.Device1.Connected")
  69.     if !connected.Value().(bool) {
  70.         log.Println("Not connected, trying to connect")
  71.         obj.Call("org.bluez.Device1.Connect", dbus.FlagNoAutoStart)
  72.         connected, _ = obj.GetProperty("org.bluez.Device1.Connected")
  73.     }
  74.     if connected.Value().(bool) {
  75.         log.Println("Connected waiting for connection to terminate")
  76.         waitForChange(conn, devicepath)
  77.         return true
  78.     }
  79.     return false
  80. }
  81.  
  82. func sendNotification(conn *dbus.Conn, message string, replaceId uint32) uint32 {
  83.     iconName := "mail-unread"
  84.     n := notify.Notification{
  85.         AppName:       "BT Autolocker",
  86.         ReplacesID:    replaceId,
  87.         AppIcon:       iconName,
  88.         Summary:       "BT Autolocker",
  89.         Body:          message,
  90.         Actions:       []string{}, // tuples of (action_key, label)
  91.         Hints:         map[string]dbus.Variant{},
  92.         ExpireTimeout: int32(5000),
  93.     }
  94.  
  95.     // Ship it!
  96.     createdID, _ := notify.SendNotification(conn, n)
  97.     return createdID
  98. }
  99.  
  100. func main() {
  101.     var maxidletimeflag int
  102.     var maxidletime uint32
  103.     var lockapp string
  104.     replaceId := uint32(0)
  105.     flag.IntVar(&maxidletimeflag, "idletime", 30, "Idle time before invoking lock")
  106.     flag.StringVar(&lockapp, "lockapp", "i3lock", "Command to invoe to lock")
  107.     flag.Parse()
  108.     maxidletime = uint32(maxidletimeflag * 1000)
  109.  
  110.     app, err := shlex.Split(lockapp)
  111.     if err != nil {
  112.         fmt.Println("Invalid lockapp")
  113.         os.Exit(1)
  114.     }
  115.  
  116.     devicepath := "/org/bluez/hci0/dev_A0_9E_1A_14_FE_10"
  117.     X, err := xgb.NewConn()
  118.     if err != nil {
  119.         log.Fatal(err)
  120.     }
  121.     log.Println(X.DisplayNumber)
  122.     scr := xproto.Drawable(xproto.Setup(X).DefaultScreen(X).Root)
  123.     screensaver.Init(X)
  124.  
  125.     conn, err := dbus.SystemBus()
  126.     if err != nil {
  127.         fmt.Fprintln(os.Stderr, "Failed to connect to system bus:", err)
  128.         os.Exit(1)
  129.     }
  130.     sessionbus, err := dbus.SessionBus()
  131.     if err != nil {
  132.         fmt.Fprintln(os.Stderr, "Failed to connect to session bus:", err)
  133.         os.Exit(1)
  134.     }
  135.  
  136.     sendNotification(sessionbus, "Autolocker started", replaceId)
  137.  
  138.     for {
  139.         idletime, _ := getIdleTime(X, scr)
  140.         if idletime < maxidletime {
  141.             sleeptime := maxidletime - idletime
  142.             log.Println("Sleeping for ", sleeptime/1000)
  143.             time.Sleep(time.Duration(sleeptime) * time.Millisecond)
  144.             continue
  145.         }
  146.         if !tryConnect(conn, devicepath) {
  147.             sendNotification(sessionbus, "Locking in 5 seconds", replaceId)
  148.             time.Sleep(time.Duration(5) * time.Second)
  149.             if isIdle(X, scr, maxidletime) {
  150.                 log.Println("Locking now")
  151.                 lock(app)
  152.                 time.Sleep(time.Duration(5) * time.Second)
  153.             }
  154.         } else {
  155.             lock(app)
  156.  
  157.         }
  158.     }
  159.  
  160. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top