Traccia il tempo del progetto con Alfred Timekeeper

Cosa starai creando

Alfred Time Keeper

Molte persone destreggiano tra più progetti con orari diversi. Dalle app Web ai programmi dedicati, esistono già diversi modi per tenere traccia del tempo trascorso in un progetto. La maggior parte richiede un servizio di rete e / o un programma per rimanere sempre in esecuzione. Spesso questo non è pratico.

Alfred Timekeeper funziona in modo simile a un sistema di mantenimento del tempo delle schede perforate: si salva un timestamp quando si avvia e si smette di funzionare. Poiché registra solo timestamp, un programma o un servizio web non è sempre aperto.

In questo tutorial, presumo che tu abbia già familiarità con la scrittura di flussi di lavoro in Alfred. In caso contrario, consulta questi tutorial: Alfred for Beginners, Intermediates, Advanced users e Alfred Debugging.

Design generale

Molte persone lavorano con computer diversi in luoghi diversi. Ciò rende molto più difficile tenere traccia dei progetti e della gestione del tempo. Usando Dropbox, tutte le informazioni sulla gestione del tempo e del progetto sono sincronizzate automaticamente.

Questo approccio richiede la conservazione di tutte le informazioni nei file e non nella memoria del computer. Questa restrizione richiede l'uso di due disposizioni per l'archiviazione dei dati: directory locale di informazioni utilizzate solo dal programma di quel sistema e a directory sincronizzata questo è condiviso con ogni computer collegato ad esso.

La memoria locale contiene il riferimento alla directory sincronizzata e l'editor per modificare i timesheet. Questi file si trovano nella posizione della directory dei dati di Alfred.

La directory sincronizzata conserva tutti i timesheet, gli elenchi dei progetti, l'ultimo stato conosciuto delle informazioni di registrazione e le informazioni sul fuso orario. Quello sarà in una posizione Dropbox. È possibile utilizzare qualsiasi sistema di sincronizzazione del file system, mi è capitato di avere già Dropbox.

Creazione del flusso di lavoro

In Alfred, creare un nuovo flusso di lavoro chiamato Cronometro Alfred.

Creazione del flusso di lavoro

In questo nuovo flusso di lavoro, è necessario creare un Filtro file che elencherà solo le directory.

Imposta Comando directory delle schede delle attività

È possibile impostare il Tipi di file trascinando una directory da mirino al Tipi di file la zona. Impostare il Ambito di ricerca alla directory che contiene il tuo account DropBox.

Aggiungere un Esegui script bloccare dopo questo blocco, deselezionando tutte le opzioni di escape. A quel blocco, aggiungi questo script:

######################### # Contanti. ######################### VPREFS = "$ HOME /Library/Caches/com.runningwithcrayons.Alfred-2/Workflow Data /" NVPREFS = "$ HOME / Libreria / Supporto applicazione / Alfred 2 / Dati flusso di lavoro /" ############################################# ############################################### # Leggi il bundleid dal flusso di lavoro info.plist ################################################################################################## ################################### getBundleId () / usr / libexec / PlistBuddy -c "Stampa: bundleid "" info.plist " ########################################### #################################### # Ottieni la dir dei dati del flusso di lavoro ######## ################################################## #################### getDataDir () local BUNDLEID = $ (getBundleId) echo "$ NVPREFS $ BUNDLEID" se [! -d "$ (getDataDir)"]; then mkdir -p "$ (getDataDir)"; toccare "$ (getDataDir) /dir.txt"; toccare "$ (getDataDir) /editor.txt"; fi # Memorizza le informazioni della directory. echo "query"> "$ (getDataDir) /dir.txt"; # Dillo all'utente. echo "Imposta la directory su" query "."; 

Questo script controlla che la directory dei dati sia lì. In caso contrario, crea la directory e i file utilizzati per il flusso di lavoro. Prende l'input nel Interrogazione macro e lo colloca nel dir.txt file nella directory dei dati. Quindi informa l'utente dell'azione.

Connetti il Esegui script blocco a un blocco di notifica. Tutti Esegui script i blocchi da qui in poi dovrebbero connettersi a questo blocco di notifica. Imposta il suo output come il Interrogazione macro e impostare il Mostra solo se passata in argomento ha contenuto.

Una volta salvato, imposta la directory della scheda attività. All'interno della directory Dropbox, crea una directory per i timesheet e usa il ATK: setdir comando per impostare quella directory. Ora stai eseguendo un programma di cronometraggio su più sistemi!

Questa è la routine di impostazione di base per il flusso di lavoro. Prima di affrontare il programma principale, è necessario configurare l'ambiente di lavoro.

Impostazione dell'ambiente Go

Il modo più semplice per installare il linguaggio di programmazione go è vicino homebrew. Se non hai installato homebrew ancora, il tutorial Homebrew Demystified: Ultimate Package Manager di OS X ti mostrerò come.

In un terminale, digitare:

brew install go 

Nella directory home, crea la directory partire. La lingua go memorizzerà tutte le librerie scaricate lì. Aggiungi al .bashrc file e / o .zshrc file questa riga:

export GOPATH = "/ Utenti //partire" 

Se usi il pesce, aggiungi questo al config.fish file:

set -xg GOPATH "/ Utenti //partire" 

Dopo aver ricaricato la shell, puoi installare la libreria goAlfred digitando:

vai a ottenere github.com/raguay/goAlfred 

Questa libreria rende molto più facile l'utilizzo della lingua go con Alfred. Creerà le directory nell'area di archiviazione dei dati per i flussi di lavoro Alfred e renderà necessaria la lista XML Filtri di script.

Timekeeper.go

Per creare il file di programma principale, devi andare alla directory per il flusso di lavoro. Apri il Esegui script bloccare.

Apertura della directory del flusso di lavoro

Clicca il Aprire la cartella del flusso di lavoro pulsante nella parte inferiore del script: la zona. Questo apre la directory del flusso di lavoro in mirino (o esploratore se ce l'hai). Per aprire la directory in una shell di terminale, è possibile utilizzare Alfred Workflow TerminalFinder per aprire una directory Finder o Path Finder in una sessione terminale (o iTerm).

Creazione del file di programma nel terminale

Una volta nel programma del terminale, digitare:

tocca Timekeeper.go 

Apri quel file nell'editor di scelta. Una volta aperto, inserisci questo codice in:

pacchetto principale // // Programma: TimeKeeper.go // // Descrizione: Questo programma esegue la logica di feedback per selezionare lo stato on / off per // il progetto attualmente a tempo. // // // Importa le librerie che usiamo per questo programma. // import ("fmt" "github.com/raguay/goAlfred" "io" "io / ioutil" "os" "regexp" "strconv" "stringhe" "time") // // Impostazioni e costanti utilizzate . // // MAXPROJECTS Questo è il numero massimo di progetti consentiti. // TSDir Questo mantiene il nome della directory per i time sheet. È un percorso completo. // const (MAXPROJECTS int = 20) var TSDir = "" // // Funzione: main // // Descrizione: Questa è la funzione principale del programma TimeKeeper. Prende la riga di comando // e la analizza per la corretta funzionalità. // func main () if len (os.Args)> 1 switch os.Args [1] [0] case 'm': // // atk: month // SystemViewMonth () case 'w': // // atk: week // SystemViewWeek () case 't': // // atk: current // SystemViewDate () case 'r': // // atk: remove // ​​RemoveProject () case 'c' : // // atk: progetto // ChangeProject () case 'b': // // atk: current // SystemViewDay () case 'a': // // atk: addproject // AddProject () case 'o ': // // atk: state // StopStart () case' p ': // // Utilizzato per atk: progetto script fileter // project () case' T ': // // atk: time // SystemAllProjects () case 's': fallthrough default: // // Utilizzato per il filtro script su atk: stato // stato () // // Funzione: getTimeSheetDir // // Descrizione: questa funzione viene utilizzata per memorizzare nella cache una copia della directory time // sheet e darla nel ritorno. // func getTimeSheetDir () string if strings.Contains ("", TSDir) Nome file: = goAlfred.Data () + "/dir.txt" buf, err: = ioutil.ReadFile (Nome file) se err == nil // // Converti il ​​percorso della directory in una stringa e tagliala. // TSDir = strings.TrimSpace (string (buf)) // // Restituisce la directory agli orari. // return (TSDir) // // Funzione: SystemAllProjects // // Descrizione: Questa funzione mostrerà al terminale l'ora per tutti i progetti // il giorno indicato nella riga di comando successiva. // func SystemAllProjects () // // Ottieni la data corrente nel caso in cui non ce ne sia uno sulla riga di comando. // tm: = time.Now () if len (os.Args)> 2 if strings.Contains ("today", os.Args [2]) // // La data odierna. // tm = time.Now () else if strings.Contains ("ieri", os.Args [2]) // // Ieri è oggi meno un giorno. // tm = time.Now () tm = tm.AddDate (0, 0, -1) else // // Analizza la stringa data data. // tm, _ = time.Parse ("2006-Jan-02", os.Args [2]) // // Ottieni l'elenco dei nomi dei progetti. // proj: = GetListOfProjects () // // Per ogni progetto, ottenere il tempo speso per il giorno specificato. // numproj: = len (proj) - 1 per i: = 0; io < 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]) // // Restituisce la stringa. // return (clstring) // // Funzione: AddProject // // Descrizione: Questa funzione aggiungerà un nuovo progetto all'elenco dei progetti correnti. // func AddProject () // // Ottieni il nome del progetto dalla riga di comando. // proj: = GetCommandLineString () // // Crea il nome del file che contiene tutti i progetti. // projectFile: = getTimeSheetDir () + "/projects.txt" Fh, err: = os.OpenFile (projectFile, os.O_APPEND | os.O_WRONLY | os.O_CREATE, 0666) se err! = nil Fh, err = os.Create (projectFile) se err! = nil // // Il file non si aprirà. Errore. // fmt.Print ("Impossibile aprire il file di progetto:", projectFile, "\ n") os.Exit (1) // // Scrive il nuovo comando con il timestamp nel buffer. // _, err = io.WriteString (Fh, proj + "\ n") // // Perdi il file. // Fh.Close () // // Indica all'utente che il progetto è stato aggiunto. // fmt.Print ("Aggiunto progetto" + proj + "all'elenco.") // // Funzione: stato // // Descrizione: questa funzione fornisce l'output corretto per la modifica dello stato. Lo stato // prima è l'opposto rispetto allo stato corrente. // func state () // // Ottieni l'ultimo stato del progetto corrente. // stateFile: = getTimeSheetDir () + "/laststate.txt" buf, _: = ioutil.ReadFile (stateFile) curState: = string (buf) // // Imposta il primo comando al contrario dello stato corrente. In questo modo // l'utente semplicemente spinge return per alternare stati. // if strings.Contains (curState, "start") goAlfred.AddResult ("stop", "stop", "stop", "", "icon.png", "yes", "", "") goAlfred .AddResult ("start", "start", "start", "", "icon.png", "yes", "", "") else goAlfred.AddResult ("start", "start", " start "," "," icon.png "," yes "," "," ") goAlfred.AddResult (" stop "," stop "," stop "," "," icon.png "," sì " , "", "") // // Stampa la stringa xml. // fmt.Print (goAlfred.ToXML ()) // // Funzione: progetto // // Descrizione: Questa funzione crea un elenco dei progetti e visualizza quelli // simili all'input. // func project () // // Ottieni il nome del progetto dalla riga di comando. // proj: = GetCommandLineString () // // Imposta la nostra stringa predefinita. // goAlfred.SetDefaultString ("Alfred Time Keeper: Scusa, nessuna corrispondenza ...") // // Scarica l'ultimo progetto. // latestproject: = GetCurrentProject () // // Ottieni l'elenco dei progetti. // projects: = make ([] string, MAXPROJECTS) projects = GetListOfProjects () // // L'istruzione regexp split fornisce una stringa maggiore di quella che era stata divisa. L'ultima // stringa è un catchall. Non ha bisogno di essere incluso. // numproj: = len (projects) - 1 // // Per ogni progetto, crea una riga di risultato. Mostra tutto metti il ​​progetto corrente. // per i: = 0; io < 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]) // // Ottieni il progetto corrente. // currentProject: = GetCurrentProject () // // Esegue la funzione appropriata e stampa i risultati. // fmt.Print (StopStartProject (currentProject, cmd)) // // Funzione: GetCurrentProject // // Descrizione: Questa funzione recupera il progetto corrente dal file di stato //. // func GetCurrentProject () string // // Ottieni il progetto corrente. // Nome file: = getTimeSheetDir () + "/project.txt" buf, _: = ioutil.ReadFile (Nome file) // // Converti il ​​progetto corrente in una stringa, tagliala e restituiscila. // return (strings.TrimSpace (string (buf))) // // Funzione: SaveProject // // Descrizione: Questa funzione salverà il nome del progetto indicato nel // file di progetto corrente. // // Input: // proj Nome del nuovo progetto // func SaveProject (proj string) // // Scrivi il nuovo progetto. // Nome file: = getTimeSheetDir () + "/project.txt" err: = ioutil.WriteFile (Nome file, [] byte (proj), 0666) se err! = Nil fmt.Print ("Impossibile scrivere il file di progetto : "+ Nome file) os.Exit (1) // // Funzione: StopStartProject // // Descrizione: questa funzione viene utilizzata per impostare lo stato per il progetto specificato. // // Input: // currentProject Il progetto per attuare lo stato di. // cmd Il comando start o stop. // func StopStartProject (currentProject string, cmd string) string // // Imposta la stringa del risultato. // resultStr: = "" currentState: = GetCurrentState () // // Lo stato corrente è uguale al nuovo stato? // if strings.Contains (cmd, currentState) // // È già in quello stato. Non fare niente, ma dai un messaggio. // resultStr = "Già" + cmd + "\ n" else // // Okay, possiamo procedere con la scrittura del nuovo stato nel // file di progetto datato. Apri il file per la scrittura. // currentTime: = time.Now () Nome file: = generateTimeLogFileName (currentProject, currentTime) Fh, err: = os.OpenFile (Nome file, os.O_APPEND | os.O_WRONLY | os.O_CREATE, 0666) se err! = nil  // // Il file non si aprirà. Errore. // fmt.Print ("Impossibile aprire il file di progetto datato:", Filename, "\ n") os.Exit (1) // // Scrive il nuovo comando con il timestamp nel buffer. // str: = fmt.Sprintf ("% d:% s \ n", currentTime.Unix (), cmd) _, err = io.WriteString (Fh, str) // // Perdi il file. // Fh.Close () // // Scrivi il file laststate con il nuovo stato. // ioutil.WriteFile (getTimeSheetDir () + "/ laststate.txt", [] byte (cmd), 0666) // // Indica all'utente che è impostato. // resultStr = currentProject + "è ora" + cmd // // Restituisce la stringa risultante. // return (resultStr) // // function: GetCurrentState // // Descrizione: Questa funzione ottiene lo stato corrente del progetto. // func GetCurrentState () string // // Ottieni lo stato corrente. // Nome file: = getTimeSheetDir () + "/laststate.txt" buf, err: = ioutil.ReadFile (Nome file) currentState: = "stop" se err == nil // // Converti il ​​progetto corrente in una stringa e tagliarlo. // currentState = strings.TrimSpace (string (buf)) return currentState // // Funzione: generateTimeLogFileName // // Descrizione: Questa funzione crea il file di registro temporale in base al nome del progetto e // data. // // Input: // proj Nome del progetto // dt Data in questione // func generateTimeLogFileName (proj string, dt time.Time) string // // Genera il nome file corretto in base al nome e alla data del progetto . // filename: = getTimeSheetDir () + "/" + proj + "_" + dt.Format ("2006-01-02") + ".txt" return (nomefile) 

Questo codice definisce tutte le funzionalità di Alfred Timekeeper. Il design del programma è quello di fare diverse funzioni basate su una lettera di comando e parametri di opzioni dopo di esso. Otterrà la directory della scheda attività da Alfred e creerà i file di progetto e gli timesheet secondo necessità.

compilazione

Devi compilare il programma prima di poterlo usare. La lingua go non è una lingua interpretata, ma un linguaggio compilato. Ciò consente al programma di funzionare molto più velocemente.

Nel programma del terminale, digitare:

vai a costruire Timekeeper.go 
Compilando Timekeeper.go

Se tutto è a posto correttamente, ora dovresti avere il Cronometrista programma in quella directory. È in rosso sopra. Se qualcosa non è stato copiato correttamente e la compilazione fallisce, cerca il numero di linea indicato e confrontalo con quanto sopra. Oppure, ottenere una nuova copia dal download fornito con questo tutorial.

Aggiunta di funzioni Alfred

Con il programma finito, devi chiamarlo da Alfred. Creare un Parola chiave blocco con la parola chiave impostata su ATK: addproject. Connettilo a a Esegui script blocca e inserisci questa riga di codice:

./ TimeKeeper a "query" 

Tutti Esegui script i blocchi qui in uscita dovrebbero essere impostati per l'esecuzione bash script e nessuna delle opzioni di escape impostate. Lo script sopra permette di creare nuovi progetti. Usalo per creare i tuoi diversi progetti. Ho i progetti: Envato, CustomCT, e missioni creato per il lavoro che faccio.

Ora che hai progetti, ora devi impostarne uno come progetto corrente. Creare un Script Filter come sotto:

Script Filter per selezionare un progetto

Aggiungere un Esegui script blocca dopo di esso con il seguente script:

./ Timekeeper c "query" 
Impostazione del progetto

Ora puoi impostare il progetto su cui vuoi lavorare. Nel prompt Alfred, digitare ATK: Progetto e dovrebbe apparire un elenco dei progetti creati. Seleziona il progetto che desideri e inizierà automaticamente la sincronizzazione per te.

Pertanto, se hai selezionato il Esercitazioni progetto, c'è un file chiamato Tutorials_2014-05-05.txt (Ovvero, purché tu lo abbia creato il 5 maggio 2014). Dentro quel file c'è un timestamp, due punti e un inizio dichiarazione. Avrai anche il project.txt file con il progetto attualmente selezionato, laststate.txt file con l'ultimo stato (es: inizio o Stop), e il projects.txt file con un elenco di progetti creati.

I tempi sono iniziati, ma ora devi fermarlo. Crea un nuovo Script Filter blocco con la parola chiave impostata su ATK: Stato e lo script impostato su:

./ TimeKeeper s "query" 

Questo dovrebbe connettersi a a Esegui script blocco con lo script impostato su:

./ TimeKeeper o "query" 

Il S comando dice al programma Timekeeper di generare un output XML per lo stato successivo. Avrà automaticamente la prima opzione in XML per essere l'opposto dello stato corrente.

Cambiare gli stati di temporizzazione

Ora puoi alternare lo stato di sincronizzazione di un progetto ATK: Stato. È inoltre possibile creare tasti di scelta rapida per avviare e interrompere i tempi. Prova a farlo da solo. Non impari mai fino a quando non provi!

Aggiungere un trigger esterno

Potrebbe essere necessario un programma esterno per impostare lo stato della registrazione del tempo. Pertanto, creare un Trigger esterno bloccare come mostrato. Connetti questo blocco al precedente Esegui script bloccare.

Aggiungere un trigger esterno - Configurazione

Il Codice di esempio in basso può essere eseguito da qualsiasi programma di AppleScript attivato per l'attivazione start / stop azioni sul progetto attuale. Se sostituisci il testo test con Stop, fermerà i tempi. Se sostituisci il testo test con inizio, inizierà i tempi. Usato con Piano di controllo, puoi creare una regola per disattivare i tempi quando il computer dorme e riprende i tempi quando il computer si sveglia.

Ora che stai iniziando e fermando il tempo, devi vedere il tempo trascorso. Creare un Parola chiave bloccare con ATK: corrente. Connettilo a a Esegui script bloccare con questo script:

echo './Timekeeper b'; 

Collegalo al Notifica bloccare.

Comando Ora corrente

Quando corri ATK: corrente nel prompt di Alfred, si otterrà il tempo corrente trascorso sul progetto e lo stato corrente.

Secondo computer

Se hai un altro computer, configura Alfred per condividerlo su Dropbox. Una volta impostati, tutti i flussi di lavoro si aggiorneranno automaticamente da un computer all'altro.

Impostazione di Alfred Syncing

Seleziona il Imposta la cartella di sincronizzazione per configurare la sincronizzazione tramite Dropbox e seguire le indicazioni. Sul secondo computer, utilizzare il comando ATK: setdir per impostare la directory della scheda attività che hai creato in Dropbox. I due sistemi ora possono avviare e interrompere i tempi del progetto. Assicurati che Dropbox sia completamente sincronizzato tra le modifiche di stato.

Conclusione

Ecco le basi di Alfred Timekeeper. Il flusso di lavoro incluso nel download è la versione completa con altre funzionalità. Ora sai come creare il tuo sistema di gestione del tempo che è scalabile da utilizzare su più computer utilizzando Dropbox e non occupa risorse del computer. 

Dal momento che lo uso tutti i giorni, aggiungerò altre funzionalità come un'interfaccia web per vedere graficamente i timesheet. Se riesci a trovare altre funzionalità, prova ad aggiungerle tu stesso! È divertente lavorare con i flussi di lavoro di Alfred.