Verfolgen Sie die Projektzeit mit Alfred Timekeeper

Was Sie erstellen werden

Alfred Time Keeper

Viele Leute jonglieren mehrere Projekte mit unterschiedlichen Zeitplänen. Von Web-Apps bis hin zu speziellen Programmen gibt es bereits eine Reihe von Möglichkeiten, die für ein Projekt aufgewendete Zeit zu verfolgen. Die meisten erfordern einen Netzdienst und / oder ein Programm, um ständig ausgeführt zu werden. Das ist oft nicht praktisch.

Alfred Timekeeper arbeitet ähnlich wie ein Lochkarten-Zeithaltesystem: Sie speichern einen Zeitstempel, wenn Sie mit der Arbeit beginnen und aufhören. Da nur Zeitstempel aufgezeichnet werden, ist ein Programm oder ein Webdienst nicht immer geöffnet.

In diesem Lernprogramm gehe ich davon aus, dass Sie bereits mit dem Schreiben von Workflows in Alfred vertraut sind. Wenn nicht, schauen Sie sich diese Tutorials an: Alfred für Anfänger, Fortgeschrittene, Fortgeschrittene und Alfred Debugging.

Gesamtkonzept

Viele Leute arbeiten mit verschiedenen Computern an verschiedenen Orten. Dies macht es schwieriger, Projekte und Zeitmanagement im Auge zu behalten. Durch die Verwendung von Dropbox werden alle Projekt- und Zeitverwaltungsinformationen automatisch synchronisiert.

Dieser Ansatz erfordert, dass alle Informationen in Dateien und nicht im Computerspeicher aufbewahrt werden. Diese Einschränkung erfordert die Verwendung von zwei Datenspeicherungen: lokales Verzeichnis von Informationen, die nur vom Programm dieses Systems verwendet werden, und a synchronisiertes Verzeichnis das wird mit jedem Computer geteilt, der mit ihm verbunden ist.

Der lokale Speicher enthält den Verweis auf das synchronisierte Verzeichnis und den Editor zum Bearbeiten von Arbeitszeittabellen. Diese Dateien befinden sich im Datenverzeichnis von Alfred.

Das synchronisierte Verzeichnis enthält alle Arbeitszeittabellen, Projektlisten, den letzten bekannten Status der Aufnahmeinformationen und die Zeitzoneninformationen. Das wird sich in einem Dropbox-Speicherort befinden. Jedes Dateisystem-Synchronisationssystem kann verwendet werden, ich habe gerade Dropbox bereits.

Workflow erstellen

Erstellen Sie in Alfred einen neuen Workflow mit dem Namen Alfred Timekeeper.

Workflow erstellen

In diesem neuen Workflow müssen Sie eine Dateifilter das listet nur Verzeichnisse auf.

Legen Sie den Befehl Timesheet Directory fest

Sie können das einstellen Datentypen durch Ziehen eines Verzeichnisses aus Finder zum Datentypen Bereich. Stellen Sie das ein Suchbereich in das Verzeichnis, das Ihr DropBox-Konto enthält.

Füge hinzu ein Skript ausführen Blockieren Sie nach diesem Block, und deaktivieren Sie alle Escape-Optionen. Fügen Sie diesem Block dieses Skript hinzu:

######################### # Contants. ######################### VPREFS = "$ HOME /Library/Caches/com.runningwithcrayons.Alfred-2/Workflow Data /" NVPREFS = "$ HOME / Library / Anwendungsunterstützung / Alfred 2 / Workflow-Daten /" ############################## ############################################### # Lies das Bündel aus der info.plist des Workflows ######################################## ################################## getBundleId () / usr / libexec / PlistBuddy -c "Drucken: Bündel "" info.plist " ######################################## ################################## # # Liefert die Workflow-Daten dir ######## ################################################ ################### getDataDir () local BUNDLEID = $ (getBundleId) echo "$ NVPREFS $ BUNDLEID" wenn [! -d "$ (getDataDir)"]; dann mkdir -p "$ (getDataDir)"; Berühren Sie "$ (getDataDir) /dir.txt". Berühren Sie "$ (getDataDir) /editor.txt"; fi # Speichert die Verzeichnisinformationen. echo "query"> "$ (getDataDir) /dir.txt"; # Sagen Sie dem Benutzer. echo "Verzeichnis auf 'Abfrage' setzen."; 

Dieses Skript prüft, ob das Datenverzeichnis vorhanden ist. Ist dies nicht der Fall, werden das Verzeichnis und die für den Arbeitsablauf verwendeten Dateien erstellt. Es nimmt die Eingabe in die Abfrage Makro und platziert es in der dir.txt Datei im Datenverzeichnis. Der Benutzer wird dann über die Aktion informiert.

Verbinden Sie das Skript ausführen zu einem Benachrichtigungsblock sperren. Alles Skript ausführen Blöcke von hier an sollten sich mit diesem Benachrichtigungsblock verbinden. Stellen Sie als Ausgabe die Ausgabe ein Abfrage Makro und legen Sie die Nur anzeigen, wenn übergebenes Argument Inhalt enthält.

Legen Sie nach dem Speichern das Verzeichnis für die Arbeitszeittabelle fest. Erstellen Sie im Dropbox-Verzeichnis ein Verzeichnis für Arbeitszeittabellen und verwenden Sie die atk: setdir Befehl zum Einstellen dieses Verzeichnisses. Sie führen jetzt ein Zeitmesssystem mit mehreren Systemen aus!

Dies ist die grundlegende Setup-Routine für den Workflow. Bevor Sie sich mit dem Hauptprogramm befassen, müssen Sie die Arbeitsumgebung einrichten.

Einrichten der Go-Umgebung

Die einfachste Möglichkeit, die Programmiersprache go zu installieren, ist mit Homebrew. Wenn Sie nicht installiert haben Homebrew doch das Tutorial Homebrew Demystified: Der ultimative Paket-Manager von OS X wird dir zeigen wie.

Geben Sie in einem Terminal Folgendes ein:

brauen installieren gehen 

Erstellen Sie im Basisverzeichnis das Verzeichnis gehen. In der Sprache go werden alle heruntergeladenen Bibliotheken gespeichert. Fügen Sie dem hinzu .bashrc Datei und / oder .zshrc Datei diese Zeile:

export GOPATH = "/ Benutzer //gehen" 

Wenn Sie Fisch verwenden, fügen Sie dies dem hinzu config.fish Datei:

set -xg GOPATH "/ Benutzer //gehen" 

Nach dem erneuten Laden der Shell können Sie die goAlfred-Bibliothek installieren, indem Sie Folgendes eingeben:

Gehen Sie auf github.com/raguay/goAlfred 

Diese Bibliothek macht die Verwendung der Go-Sprache mit Alfred viel einfacher. Dadurch werden die Verzeichnisse für den Datenspeicherbereich für Alfred-Workflows erstellt und die erforderliche XML-Liste erstellt Skriptfilter.

Zeitnehmer

Um die Hauptprogrammdatei zu erstellen, müssen Sie das Verzeichnis für den Workflow aufrufen. Öffne das Skript ausführen Block.

Das Workflow-Verzeichnis öffnen

Drücke den Workflow-Ordner öffnen Knopf am unteren Rand des Skript: Bereich. Dadurch wird das Workflow-Verzeichnis in geöffnet Finder (oder Pfadfinder Wenn du es hast). Um das Verzeichnis in einer Terminal-Shell zu öffnen, können Sie mit dem Alfred Workflow TerminalFinder ein Finder- oder Path Finder-Verzeichnis in einer Terminalsitzung (oder iTerm) öffnen..

Erstellen der Programmdatei im Terminal

Geben Sie im Terminalprogramm Folgendes ein:

Berühren Sie Timekeeper.go 

Öffnen Sie diese Datei im Editor Ihrer Wahl. Nach dem Öffnen geben Sie diesen Code ein:

Paket main // // Programm: TimeKeeper.go // // Beschreibung: Dieses Programm führt die Rückkopplungslogik zum Auswählen des Ein / Aus-Zustands für das // aktuell geplante Projekt aus. // // // Importiere die Bibliotheken, die wir für dieses Programm verwenden. // import ("fmt" "github.com/raguay/goAlfred" "io" "io / ioutil" "os" "regexp" "strconv" "Zeichenfolgen" "time") // // Setup und verwendete Konstanten . // // MAXPROJECTS Dies ist die maximal zulässige Anzahl von Projekten. // TSDir Dies behält den Verzeichnisnamen für die Arbeitszeitnachweise bei. Es ist ein vollständiger Weg. // const (MAXPROJECTS int = 20) var TSDir = "" // // Funktion: main // // Beschreibung: Dies ist die Hauptfunktion für das TimeKeeper-Programm. Sie nimmt die Befehlszeile // und analysiert sie für die richtige Funktionalität. // func main () if len (os.Args)> 1 switch os.Args [1] [0] Fall 'm': // // atk: month // SystemViewMonth () Fall 'w': // // atk: week // SystemViewWeek () case 't': // // atk: current // SystemViewDate () case 'r': // // atk: remove // ​​RemoveProject () case 'c' : // // atk: project // ChangeProject () case 'b': // // atk: current // SystemViewDay () case 'a': // atk: addproject // AddProject () case 'o ': // // atk: state // StopStart () case' p ': // // Wird für atk: project script Fileter verwendet. // project () case' T ': // // atk: time // SystemAllProjects () case 's': fallthrough default: // // Wird für den Skriptfilter in atk: state // state () // // verwendet. Funktion: getTimeSheetDir // // Beschreibung: Diese Funktion wird zum Zwischenspeichern verwendet eine Kopie des // Zeitverzeichnisses und geben Sie es in der Rückgabe. // func getTimeSheetDir () string if strings.Contains ("", TSDir) Dateiname: = goAlfred.Data () + "/dir.txt" buf, err: = ioutil.ReadFile (Dateiname), wenn err == nil // // Konvertieren Sie den Verzeichnispfad in einen String und schneiden Sie ihn ab. // TSDir = strings.TrimSpace (string (buf)) // // Das Verzeichnis an die Arbeitszeitnachweise zurückgeben. // return (TSDir) // // Funktion: SystemAllProjects // // Beschreibung: Diese Funktion zeigt dem Terminal die Zeit für alle Projekte an // dem Tag an, der als nächster in der Befehlszeile angegeben ist. // func SystemAllProjects () // // Ermittelt das aktuelle Datum, falls in der Befehlszeile kein Datum angezeigt wird. // tm: = time.Now () if len (os.Args)> 2 wenn Strings.Contains ("today", os.Args [2]) // // Tagesdatum. // tm = time.Now () else if strings.Contains ("gestern", os.Args [2]) // // Gestern ist heute minus ein Tag. // tm = time.Now () tm = tm.AddDate (0, 0, -1) else // Analysiert den angegebenen Datumsstring. // tm, _ = time.Parse ("2006-Jan-02", os.Args [2]) // // Abrufen der Liste der Projektnamen. // proj: = GetListOfProjects () // // Für jedes Projekt die für den jeweiligen Tag aufgewendete Zeit abrufen. // numproj: = len (proj) - 1 für i: = 0; ich < numproj; i++  fmt.Printf("%s: %s\n", proj[i], formatTimeString(GetTimeAtDate(proj[i], tm)))   // // Function: SystemViewMonth // // Description: This function will calculate the time the current month for all the projects. // func SystemViewMonth()  // // Get the current project. // currentProject := GetCurrentProject() // // Get the time on that project for this month. The current time gives the current month. // tm := GetTimeAtMonth(currentProject, time.Now()) // // format the time string and print it out. // fmt.Print(formatTimeString(tm))  // // Function: GetTimeAtDate // // Description: This function will take a project and calculate the time spent // on that project for a particular date. // func GetTimeAtMonth(project string, date time.Time) int64  tm := int64(0) dateStart := time.Date(date.Year(), date.Month(), 1, 0, 0, 0, 0, time.UTC) // // Get the time added up for the whole week. // for i := 0; i <= date.Day(); i++  tm += GetTimeAtDate(project, dateStart.AddDate(0, 0, i))  // // Return the amount of time calculated. // return (tm)  // // Function: SystemViewWeek // // Description: This function will calculate the time the current week for all the projects. // // Inputs: // variable description // func SystemViewWeek()  currentProject := GetCurrentProject() tm := GetTimeAtWeek(currentProject, time.Now()) fmt.Print(formatTimeString(tm))  // // Function: GetTimeAtDate // // Description: This function will take a project and calculate the time spent // on that project for a particular date. // func GetTimeAtWeek(project string, date time.Time) int64  tm := int64(0) dateStart := date dateEnd := date switch date.Weekday()  case 0:  dateEnd = dateEnd.AddDate(0, 0, 6)  case 1:  dateStart = dateStart.AddDate(0, 0, -1) dateEnd = dateEnd.AddDate(0, 0, 5)  case 2:  dateStart = dateStart.AddDate(0, 0, -2) dateEnd = dateEnd.AddDate(0, 0, 4)  case 3:  dateStart = dateStart.AddDate(0, 0, -3) dateEnd = dateEnd.AddDate(0, 0, 3)  case 4:  dateStart = dateStart.AddDate(0, 0, -4) dateEnd = dateEnd.AddDate(0, 0, 2)  case 5:  dateStart = dateStart.AddDate(0, 0, -5) dateEnd = dateEnd.AddDate(0, 0, 1)  case 6:  dateStart = dateStart.AddDate(0, 0, -6)   // // Get the time added up for th whole week. // for i := 0; i < 7; i++  tm += GetTimeAtDate(project, dateStart.AddDate(0, 0, i))  return (tm)  // // Function: SystemViewDate // // Description: This function will calculate the time for projects at a certain date. // func SystemViewDate()  currentProject := GetCurrentProject() tm := GetTimeAtDate(currentProject, time.Now()) fmt.Print(formatTimeString(tm))  // // function: SystemViewDay // // Description: This function is for displaying a nice time for the current project. // func SystemViewDay()  currentProject := GetCurrentProject() tm := GetTimeAtDate(currentProject, time.Now()) ctime := formatTimeString(tm) state := GetCurrentState() fmt.Printf("The current time on %s is %s. Current state is %s.", currentProject, ctime, state)  // // Function: GetTimeAtDate // // Description: This function will take a project and calculate the time spent // on that project for a particular date. // func GetTimeAtDate(project string, date time.Time) int64  // // Get the current project. // filename := generateTimeLogFileName(project, date) tm := readDayTime(filename) return tm  // // Function: formatTimeString // // Description: This function takes the number of seconds and returns a string // in hour:minute:seconds format with zero padding. // // Input: // tm time in seconds (an int64) // func formatTimeString(tm int64) string  min := int(tm / 60) sec := tm - int64(min*60) hr := min / 60 min = min - (hr * 60) return fmt.Sprintf("%02d:%02d:%02d", hr, min, sec)  // // Function: readDayTime // // Description: This function reads a time sheet file and calculates the time // represented in that file. func readDayTime(filename string) int64  buf, _ := ioutil.ReadFile(filename) times := regexp.MustCompile("\n|\r").Split(string(buf), -1) // // Loop through all the time lines. // tmwork := int64(0) firsttime := int64(0) first := false for i := 0; i < len(times); i++  if !strings.Contains("", times[i])  // // Split by colon to time and action. // parts := strings.Split(times[i], ":") if strings.Contains("start", parts[1])  firsttime, _ = strconv.ParseInt(parts[0], 10, 64) first = true  else  tm, _ := strconv.ParseInt(parts[0], 10, 64) tmwork += tm - firsttime first = false    // // If a start was the last thing processed, that means it is still being timed. Get the // current time to see the overall time. firsttime is the time stamp when the start // was given. // if first  currentTime := time.Now() ctime := currentTime.Unix() tmwork += ctime - firsttime  // // Return the final Time. // return tmwork  // // Function: RemoveProject // // Description: This function will remove a project from the list a valid projects. // func RemoveProject()  // // Get the project name from the command line. // proj := GetCommandLineString() // // Get the list of project names. // projects := GetListOfProjects() // // Open the projects file in truncation mode to remove all the old stuff. // Filename := getTimeSheetDir() + "/projects.txt" Fh, err := os.OpenFile(Filename, os.O_TRUNC|os.O_WRONLY|os.O_CREATE, 0666) if err != nil  // // The file would not open. Error out. // fmt.Print("Could not open the projects file: ", Filename, "\n") os.Exit(1)  // // Loop through all the projects. // for i := 0; i < len(projects); i++  if !strings.Contains(proj, projects[i])  // // It is not the project to be removed. Put it into the file. // Fh.WriteString(projects[i] + "\n")   // // Close the file. // Fh.Close() // // Tell the user that the project has been removed. // fmt.Print(proj + " has been removed!")  // // Function: ChangeProject // // Description: This function will change the currently active project. If the old // project was started, it will stop it first, then set the new project // and start it. // func ChangeProject()  // // Get the project name from the command line. // proj := GetCommandLineString() // // Get the current project. // currentProject := GetCurrentProject() // // Stop the current project. // StopStartProject(currentProject, "stop") // // Save the new project to the data file. // SaveProject(proj) // // Start the new project. // StopStartProject(proj, "start") // // Tell the user it is started. // fmt.Print("The current project is now " + proj + " and is started.")  // // Function: GetCommandLineString // // Description: This function is used to get the after the function if there is one. // If not, then just return nothing. // func GetCommandLineString() string  // // See if we have any input other then the command. // clstring := "" if len(os.Args) > 2 clstring = strings.TrimSpace (os.Args [2]) // // Liefert die Zeichenfolge. // return (clstring) // // Funktion: AddProject // // Beschreibung: Diese Funktion fügt der Liste der aktuellen Projekte ein neues Projekt hinzu. // func AddProject () // // Ruft den Projektnamen über die Befehlszeile ab. // proj: = GetCommandLineString () // // Erstellen Sie den Dateinamen, der alle Projekte enthält. // projectFile: = getTimeSheetDir () + "/projects.txt" Fh, err: = os.OpenFile (projectFile, os.O_APPEND | os.O_WRONLY | os.O_CREATE, 0666) if err! = nil Fh, err = os.Create (projectFile) if err! = nil // // Die Datei konnte nicht geöffnet werden. Fehler raus // fmt.Print ("Projektdatei konnte nicht geöffnet werden:", projectFile, "\ n") os.Exit (1) // // Schreibe den neuen Befehl mit dem Zeitstempel in den Puffer. // _, err = io.WriteString (Fh, proj + "\ n") // // Die Datei verlieren. // Fh.Close () // // Dem Benutzer mitteilen, dass das Projekt hinzugefügt wird. // fmt.Print ("Projekt hinzugefügt" + proj + "zur Liste hinzugefügt.") // // Funktion: state // // Beschreibung: Diese Funktion liefert die richtige Ausgabe zum Ändern des Status. // state ist derjenige, der dem aktuellen Status entgegengesetzt ist. // func state () // // Den letzten Status des aktuellen Projekts abrufen. // stateFile: = getTimeSheetDir () + "/laststate.txt" buf, _: = ioutil.ReadFile (stateFile) curState: = string (buf) // // Setzt den ersten Befehl auf das Gegenteil des aktuellen Status. Auf diese Weise // drückt der Benutzer einfach die Rückkehr zu den Umschaltzuständen. // if strings.Contains (curState, "start") goAlfred.AddResult ("stop", "stop", "stop", "", "icon.png", "yes", "", "")) goAlfred .AddResult ("start", "start", "start", "," icon.png "," ja "," "," ") else goAlfred.AddResult (" start "," start "," start "," "," icon.png "," ja "," "," ") goAlfred.AddResult (" stop "," stop "," stop "," "," icon.png "," yes " , "", "") // // Ausdruck der XML-Zeichenfolge. // fmt.Print (goAlfred.ToXML ()) // // Funktion: Projekt // // Beschreibung: Diese Funktion erstellt eine Liste der Projekte und zeigt // die der Eingabe ähnlichen an. // func project () // // Liefert den Projektnamen von der Kommandozeile. // proj: = GetCommandLineString () // // Legt unsere Standardzeichenfolge fest. // goAlfred.SetDefaultString ("Alfred Time Keeper: Entschuldigung, keine Übereinstimmung ...") // // Holen Sie sich das neueste Projekt. // latestproject: = GetCurrentProject () // // Liefert die Liste der Projekte. // projects: = make ([] string, MAXPROJECTS) projects = GetListOfProjects () // // Die regexp split-Anweisung gibt eine Zeichenfolge mehr als gespalten aus. Der letzte // String ist ein Catchall. Es muss nicht enthalten sein. // numproj: = len (projects) - 1 // // Erstellen Sie für jedes Projekt eine Ergebniszeile. Alle anzeigen, das aktuelle Projekt einfügen. // für i: = 0; ich < numproj; i++  if !strings.Contains(projects[i], latestproject)  goAlfred.AddResultsSimilar(proj, projects[i], projects[i], projects[i], "", "icon.png", "yes", "", "")   // // Print out the xml string. // fmt.Print(goAlfred.ToXML())  // // Function: GetListOfProjects // // Description: This function will return an array of string with the names of the project. // func GetListOfProjects() []string  // // Create the projects array and populate it. // projectFile := getTimeSheetDir() + "/projects.txt" buf, _ := ioutil.ReadFile(projectFile) // // Split out the different project names into separate strings. // return (regexp.MustCompile("\n|\r").Split(string(buf), -1))  // // Function: StopStart // // Description: This will place a start or stop time stamp for the current project and // current date. // func StopStart()  // // See if we have any input other then the command. If not, assume a stop command. // cmd := "stop" if len(os.Args) > 2 cmd = strings.ToLower (os.Args [2]) // // Das aktuelle Projekt abrufen. // currentProject: = GetCurrentProject () // // Führen Sie die entsprechende Funktion aus und drucken Sie die Ergebnisse. // fmt.Print (StopStartProject (currentProject, cmd)) // // Funktion: GetCurrentProject // // Beschreibung: Diese Funktion ruft das aktuelle Projekt aus der // Statusdatei ab. // func GetCurrentProject () string // // Das aktuelle Projekt abrufen. // Dateiname: = getTimeSheetDir () + "/project.txt" buf, _: = ioutil.ReadFile (Dateiname) // // Konvertieren Sie das aktuelle Projekt in eine Zeichenfolge, schneiden Sie es ab und geben Sie es zurück. // return (strings.TrimSpace (string (buf))) // // Funktion: SaveProject // // Beschreibung: Diese Funktion speichert den angegebenen Projektnamen in der // aktuellen Projektdatei. // // Eingaben: // proj Name des neuen Projekts // func SaveProject (proj string) // // Schreibe das neue Projekt. // Dateiname: = getTimeSheetDir () + "/project.txt" err: = ioutil.WriteFile (Dateiname, [] Byte (proj), 0666) if err! = Nil fmt.Print ("Projektdatei kann nicht geschrieben werden : "+ Dateiname) os.Exit (1) // // Funktion: StopStartProject // // Beschreibung: Mit dieser Funktion wird der Status für das angegebene Projekt festgelegt. // // Eingaben: // currentProject Das Projekt, auf das der Status von angewendet wird. // cmd Der Start- oder Stoppbefehl. // func StopStartProject (aktuelleProjektzeichenfolge, Cmd-Zeichenfolge) Zeichenfolge // // Die Ergebniszeichenfolge einrichten. // resultStr: = "" currentState: = GetCurrentState () // // Ist der aktuelle Status derselbe wie der neue Status? // if strings.Contains (cmd, currentState) // // Es befindet sich bereits in diesem Status. Nichts tun, aber eine Nachricht geben. // resultStr = "Schon" + cmd + "\ n" else // // Okay, wir können mit dem Schreiben des neuen Status in die // datierte Projektdatei fortfahren. Öffnen Sie die Datei zum Schreiben. // currentTime: = time.Now () Dateiname: = generateTimeLogFileName (currentProject, currentTime) Fh, err: = os.OpenFile (Dateiname, os.O_APPEND | os.O_WRONLY | os.O_CREATE, 0666) if err! = nil  // // Die Datei konnte nicht geöffnet werden. Fehler raus // fmt.Print ("Die datierte Projektdatei konnte nicht geöffnet werden:", Dateiname, "\ n") os.Exit (1) // // Schreibe den neuen Befehl mit dem Zeitstempel in den Puffer. // str: = fmt.Sprintf ("% d:% s \ n", currentTime.Unix (), cmd) _, err = io.WriteString (Fh, str) // // Lose die Datei. // Fh.Close () // // Schreibe die letzte Statusdatei mit dem neuen Status. // ioutil.WriteFile (getTimeSheetDir () + "/ laststate.txt", [] Byte (cmd), 0666) // // Informieren Sie den Benutzer, dass diese Einstellung festgelegt ist. // resultStr = currentProject + "ist jetzt" + cmd // // Gibt die resultierende Zeichenfolge zurück. // return (resultStr) // // function: GetCurrentState // // Beschreibung: Diese Funktion ruft den aktuellen Status des Projekts ab. // func GetCurrentState () string // // Den aktuellen Status abrufen. // Dateiname: = getTimeSheetDir () + "/laststate.txt" buf, err: = ioutil.ReadFile (Dateiname) currentState: = "stop" wenn err == nil // // Konvertiert das aktuelle Projekt in eine Zeichenfolge und trimmen Sie es. // currentState = strings.TrimSpace (string (buf)) return currentState // // Funktion: generateTimeLogFileName // // Beschreibung: Diese Funktion erstellt die Zeitprotokolldatei basierend auf dem Projektnamen und dem // Datum. // // Eingaben: // proj Name des Projekts // dt Datum in Frage // func generateTimeLogFileName (proj string, dt time.Time) string // // Generiere den richtigen Dateinamen basierend auf dem Projektnamen und dem Datum . // Dateiname: = getTimeSheetDir () + "/" + proj + "_" + dt.Format ("2006-01-02") + ".txt" Rückgabe (Dateiname) 

Dieser Code definiert die gesamte Funktionalität des Alfred Timekeeper. Das Design des Programms besteht darin, verschiedene Funktionen basierend auf einem Befehlsbuchstaben und den darauf folgenden Optionen auszuführen. Es wird das Arbeitszeittabellenverzeichnis von Alfred abrufen und die Projektdateien und Arbeitszeittabellen nach Bedarf erstellen.

Kompilieren

Sie müssen das Programm kompilieren, bevor Sie es verwenden können. Die Go-Sprache ist keine interpretierte Sprache, sondern eine kompilierte Sprache. Dadurch kann das Programm viel schneller ausgeführt werden.

Geben Sie im Terminalprogramm Folgendes ein:

Bauen Sie Timekeeper.go auf 
Timekeeper.go wird kompiliert

Wenn alles richtig ist, sollten Sie jetzt die Zeitnehmer Programm in diesem Verzeichnis. Es ist in rot oben. Wenn etwas nicht richtig kopiert wurde und das Kompilieren fehlschlägt, suchen Sie die angegebene Zeilennummer und vergleichen Sie sie mit der obigen. Oder holen Sie sich eine neue Kopie von dem Download, der in diesem Tutorial enthalten ist.

Hinzufügen von Alfred-Funktionen

Wenn das Programm beendet ist, müssen Sie es von Alfred anrufen. Ein ... kreieren Stichwort Blockieren Sie das Schlüsselwort auf atk: addproject. Verbinden Sie es mit einem Skript ausführen Blockieren und setzen Sie diese Codezeile:

./ TimeKeeper eine "Abfrage" 

Alles Skripts ausführen Blöcke hier auf out sollten gesetzt werden bash Skripts und keine der festgelegten Escape-Optionen. Das obige Skript ermöglicht das Erstellen neuer Projekte. Verwenden Sie dies, um Ihre verschiedenen Projekte zu erstellen. Ich habe die Projekte: Envato, CustomCT, und Missionen Für meine Arbeit geschaffen.

Jetzt, wo Sie Projekte haben, müssen Sie jetzt eines als aktuelles Projekt festlegen. Ein ... kreieren Skriptfilter wie nachstehend:

Skriptfilter zur Auswahl eines Projekts

Füge hinzu ein Skript ausführen Blockieren Sie danach mit folgendem Skript:

./ Zeitnehmer c "query" 
Projekt einstellen

Jetzt können Sie das Projekt festlegen, an dem Sie arbeiten möchten. Geben Sie im Alfred-Prompt ein atk: projekt und eine Liste der erstellten Projekte sollte angezeigt werden. Wählen Sie das gewünschte Projekt aus und das Timing beginnt automatisch für Sie.

Wenn Sie also das ausgewählt haben Tutorials Projekt gibt es eine Datei mit dem Namen Tutorials_2014-05-05.txt (Das heißt, solange Sie es am 5. Mai 2014 erstellt haben). In dieser Datei befinden sich ein Zeitstempel, ein Doppelpunkt und ein Start Aussage. Sie werden auch die haben project.txt Datei mit dem aktuell ausgewählten Projekt, laststate.txt Datei mit dem letzten Status (dh: Start oder halt), und das projects.txt Datei mit einer Liste der erstellten Projekte.

Das Timing hat begonnen, aber jetzt müssen Sie es stoppen. Erstelle eine neue Skriptfilter Blockieren Sie das Schlüsselwort auf atk: state und das Skript auf:

./ TimeKeeper s "query" 

Das sollte sich mit einem verbinden Skript ausführen Blockieren Sie das Skript auf:

./ TimeKeeper o "Abfrage" 

Das s Befehl weist das Timekeeper-Programm an, eine XML-Ausgabe für den nächsten Status zu generieren. Es wird automatisch die erste Option in XML angezeigt, die dem aktuellen Status entgegengesetzt ist.

Timing-Status ändern

Sie können jetzt den zeitlichen Status eines Projekts mit umschalten atk: state. Sie können auch Hotkeys erstellen, um das Timing zu starten und zu stoppen. Versuchen Sie, das alleine zu machen. Sie lernen nie, bis Sie es versuchen!

Hinzufügen eines externen Auslösers

Möglicherweise möchten Sie ein externes Programm, um den Status der Zeitaufzeichnung festzulegen. Deshalb erstellen Sie eine Externer Auslöser blockieren wie gezeigt. Verbinden Sie diesen Block mit dem vorherigen Skript ausführen Block.

Externen Trigger hinzufügen - Konfiguration

Das Beispielcode unten kann von jedem AppleScript-fähigen Programm zum Auslösen ausgeführt werden Start stop Aktionen für das aktuelle Projekt. Wenn Sie den Text ersetzen Prüfung mit halt, es wird das Timing stoppen. Wenn Sie den Text ersetzen Prüfung mit Start, es wird das Timing beginnen. Benutzt mit Steuerungsfläche, Sie können eine Regel erstellen, um die Zeiteinstellung für den Ruhezustand des Computers zu deaktivieren und die Zeitmessung wieder aufzunehmen, wenn der Computer wach wird.

Jetzt, wo Sie die Zeit starten und stoppen, müssen Sie die aufgewendete Zeit anzeigen. Ein ... kreieren Stichwort blockieren mit atk: aktuell. Verbinden Sie es mit einem Skript ausführen Block mit diesem Skript:

echo './Timekeeper b'; 

Verbinden Sie es mit dem Benachrichtigung Block.

Aktueller Zeitbefehl

Wenn du rennst atk: aktuell In der Eingabeaufforderung von Alfred erhalten Sie die aktuelle Zeit für das Projekt und den aktuellen Status.

Zweiter Computer

Wenn Sie über einen anderen Computer verfügen, richten Sie Alfred für die Freigabe über Dropbox ein. Nach der Einrichtung werden alle Ihre Workflows automatisch von einem Computer zum anderen aktualisiert.

Einrichten der Alfred-Synchronisierung

Wähle aus Legen Sie den Sync-Ordner fest um die Synchronisierung über Dropbox einzurichten und folgen Sie den Anweisungen. Verwenden Sie auf dem zweiten Computer den Befehl atk: setdir um das in Dropbox erstellte Arbeitszeittabellenverzeichnis festzulegen. Die beiden Systeme können jetzt Projektzeiten starten und stoppen. Stellen Sie sicher, dass Dropbox zwischen Statusänderungen vollständig synchronisiert ist.

Fazit

Das sind die Grundlagen des Alfred Timekeeper. Der mit dem Download gelieferte Workflow ist die Vollversion mit anderen Funktionen. Sie wissen nun, wie Sie ein eigenes Zeitverwaltungssystem erstellen, das mit Dropbox auf mehreren Computern verwendet werden kann und keine Computerressourcen beansprucht. 

Da ich dies täglich verwende, füge ich weitere Funktionen hinzu, beispielsweise ein Web-Interface, um die Arbeitszeittabellen grafisch anzuzeigen. Wenn Sie andere Funktionen entwickeln können, versuchen Sie, diese selbst hinzuzufügen! Das macht Spaß, mit Alfred Workflows zu arbeiten.