Volg projecttijd met Alfred Timekeeper

Wat je gaat creëren

Alfred Time Keeper

Veel mensen jongleren met meerdere projecten met verschillende tijdschema's. Van webapps tot speciale programma's, er is al een aantal manieren om de tijd die aan een project wordt besteed bij te houden. De meesten eisen dat net-service en / of een programma de hele tijd draait. Vaak is dit niet praktisch.

Alfred Timekeeper werkt op dezelfde manier als een tijdkaartsysteem voor ponskaarten: u slaat een tijdstempel op wanneer u begint en stopt met werken. Aangezien het alleen tijdstempels registreert, is een programma of webservice niet altijd open.

In deze zelfstudie ga ik ervan uit dat u al bekend bent met schrijfworkflows in Alfred. Als dat niet het geval is, bekijk dan deze tutorials: Alfred for Beginners, Intermediates, Advanced users en Alfred Debugging.

Algemeen ontwerp

Veel mensen werken met verschillende computers op verschillende locaties. Dat maakt het bijhouden van projecten en timemanagement veel moeilijker. Door Dropbox te gebruiken, worden alle project- en tijdbeheerinformatie automatisch gesynchroniseerd.

Deze aanpak vereist het bewaren van alle informatie in bestanden en niet in het computergeheugen. Deze beperking vereist het gebruik van twee gegevensopslagvoorzieningen: lokale map van informatie die alleen door het programma van dat systeem wordt gebruikt, en a gesynchroniseerde map die wordt gedeeld met elke computer die erop is aangesloten.

De lokale opslag bevat de verwijzing naar de gesynchroniseerde map en de editor om de urenstaten te bewerken. Deze bestanden bevinden zich op de gegevenslocatie van Alfred.

De gesynchroniseerde map bewaart alle urenstaten, lijsten met projecten, laatst bekende staat van opname-informatie en de tijdzone-informatie. Dat gebeurt op een Dropbox-locatie. Elk bestandssysteem synchronisatiesysteem kan worden gebruikt, ik heb toevallig al Dropbox.

De workflow maken

Maak in Alfred een nieuwe workflow genaamd Alfred Timekeeper.

De workflow maken

In deze nieuwe workflow moet u een Bestandsfilter die alleen mappen zal weergeven.

Stel Timesheet Directory Command in

U kunt de Bestand types door een map te verslepen vinder naar de Bestand types Gebied. Stel de Zoek bereik naar de map met uw DropBox-account.

Voeg een ... toe Voer het script uit blok na dit blok, deselecteer alle ontsnappingsopties. Voeg aan dat blok dit script toe:

######################### # Contants. ######################### VPREFS = "$ HOME /Library/Caches/com.runningwithcrayons.Alfred-2/Workflow Data /" NVPREFS = "$ HOME / Bibliotheek / Application Support / Alfred 2 / Workflow Data /" ############################### ############################################### # Lees de bundleid uit de workflow's info.plist ####################################### ################################### getBundleId () / usr / libexec / PlistBuddy -c "Print: bundleid "" info.plist " ################## #################################### # Haal de workflowgegevens op ######## ################################################## #################### getDataDir () local BUNDLEID = $ (getBundleId) echo "$ NVPREFS $ BUNDLEID" if [! -d "$ (getDataDir)"]; dan mkdir -p "$ (getDataDir)"; raak "$ (getDataDir) /dir.txt" aan; raak "$ (getDataDir) /editor.txt" aan; fi # Bewaar de directory-informatie. echo "query"> "$ (getDataDir) /dir.txt"; # Vertel de gebruiker. echo "Stel de map in op 'query'."; 

Dit script controleert of de datadirectory er is. Als dat niet het geval is, worden de map en de bestanden voor de werkstroom gemaakt. Het neemt de invoer in de Zoekopdracht macro en plaatst deze in de dir.txt bestand in de gegevensdirectory. Vervolgens wordt de gebruiker op de hoogte gesteld van de actie.

Verbind de Voer het script uit blokkeren naar een meldingsblok. Allemaal Voer het script uit blokken vanaf hier moeten verbinding maken met dit meldingsblok. Stel de uitvoer in op de Zoekopdracht macro en stel de Laat alleen zien of het ingeleverde argument inhoud bevat.

Na het opslaan stelt u de urenoverzichtsdirectory in. Maak in de Dropbox-map een map voor timesheets en gebruik de atk: setdir commando om die map in te stellen. U voert nu een tijdprogramma voor meerdere systemen uit!

Dat is de basisinstellingsroutine voor de werkstroom. Voordat u het hoofdprogramma aanpakt, moet u de werkomgeving instellen.

De Go-omgeving instellen

De eenvoudigste manier om de programmeertaal Go te installeren, is door homebrew. Als je het nog niet hebt geïnstalleerd homebrew maar toch, de zelfstudie Homebrew Demystified: OS X's Ultimate Package Manager zal je laten zien hoe.

Typ in een terminal:

brouw installeer ga 

Maak de map in de homedirectory Gaan. De go-taal slaat alle gedownloade bibliotheken daar op. Toevoegen aan de .bashrc bestand en / of .zshrc bestand deze lijn:

export GOPATH = "/ Gebruikers //Gaan" 

Als je vis gebruikt, voeg je dit toe aan de config.fish het dossier:

set -xg GOPATH "/ Gebruikers //Gaan" 

Nadat u de shell opnieuw hebt geladen, kunt u de goAlfred-bibliotheek installeren door het volgende te typen:

ga naar github.com/raguay/goAlfred 

Deze bibliotheek maakt het gebruik van de go-taal met Alfred veel eenvoudiger. Het maakt de mappen naar het gegevensopslaggebied voor Alfred-werkstromen en maakt de XML-lijst nodig Scriptfilters.

Timekeeper.go

Als u het hoofdprogrammabestand wilt maken, moet u naar de map voor de werkstroom gaan. Open de Voer het script uit blok.

De workflow-map openen

Klik op de Open workflowmap knop onderaan de Script: Gebied. Hiermee wordt de werkstroommap geopend in vinder (of verkenner als je het hebt). Om de directory in een terminalshell te openen, kunt u de Alfred Workflow TerminalFinder gebruiken om een ​​Finder- of Path Finder-map te openen in een terminalsessie (of iTerm).

Het programmabestand maken in Terminal

Typ in het terminalprogramma:

raak Timekeeper.go aan 

Open dat bestand in de editor van keuze. Eenmaal geopend, plaats deze code in:

package main // // Programma: TimeKeeper.go // // Beschrijving: dit programma voert de feedbacklogica uit voor het selecteren van de aan / uit-status voor // het momenteel getimede project. // // // Importeer de bibliotheken die we gebruiken voor dit programma. // import ("fmt" "github.com/raguay/goAlfred" "io" "io / ioutil" "os" "regexp" "strconv" "strings" "time") // // Setup en constanten die worden gebruikt . // // MAXPROJECTS Dit is het maximale aantal toegestane projecten. // TSDir Dit houdt de mapnaam voor de urenstaten bij. Het is een compleet pad. // const (MAXPROJECTS int = 20) var TSDir = "" // // Functie: hoofd // // Beschrijving: dit is de hoofdfunctie van het programma TimeKeeper. Het neemt de commandoregel // en parseert het voor de juiste functionaliteit. // 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: project // ChangeProject () case 'b': // // atk: current // SystemViewDay () case 'a': // // atk: addproject // AddProject () case 'o ': // // atk: state // StopStart () case' p ': // // Gebruikt voor atk: project script fileter // project () case' T ': // // atk: time // SystemAllProjects () case 's': fallthrough default: // // Gebruikt voor het scriptfilter op atk: state // state () // // Functie: getTimeSheetDir // // Beschrijving: deze functie wordt gebruikt voor cache een kopie van de tijd // bladdirectory en geef deze in de retour. // func getTimeSheetDir () string if strings.Contains ("", TSDir) Bestandsnaam: = goAlfred.Data () + "/dir.txt" buf, err: = ioutil.ReadFile (Bestandsnaam) if err == nil // // Converteer het mappad naar een string en knip het in. // TSDir = strings.TrimSpace (string (buf)) // // Zet de map terug in de tijdbladen. // return (TSDir) // // Functie: SystemAllProjects // // Beschrijving: deze functie geeft aan de terminal de tijd weer voor alle projecten op // de dag die wordt vermeld op de volgende opdrachtregel. // func SystemAllProjects () // // Krijg de huidige datum voor het geval er geen is op de opdrachtregel. // tm: = time.Now () if len (os.Args)> 2 if strings.Contains ("today", os.Args [2]) // // De datum van vandaag. // tm = time.Now () else if strings.Contains ("yesterday", os.Args [2]) // // Gisteren is vandaag min één dag. // tm = time.Now () tm = tm.AddDate (0, 0, -1) else // // Ontleed de gegevenstekenreeks. // tm, _ = time.Parse ("2006-Jan-02", os.Args [2]) // // Verkrijg de lijst met projectnamen. // proj: = GetListOfProjects () // // Haal voor elk project de tijd die eraan is besteed voor de opgegeven dag. // numproj: = len (proj) - 1 voor i: = 0; ik < 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]) // // Stuur de string terug. // return (clstring) // // Functie: AddProject // // Beschrijving: met deze functie wordt een nieuw project toegevoegd aan de lijst met huidige projecten. // func AddProject () // // Haal de projectnaam op vanaf de opdrachtregel. // proj: = GetCommandLineString () // // Maak de bestandsnaam die alle projecten bevat. // 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 // // Het bestand zou niet kunnen worden geopend. Foutmelding. // fmt.Print ("Kon het projectbestand niet openen:", projectFile, "\ n") os.Exit (1) // // Schrijf de nieuwe opdracht met de tijdstempel naar de buffer. // _, err = io.WriteString (Fh, proj + "\ n") // // Verlies het bestand. // Fh.Close () // // Vertel de gebruiker dat het project is toegevoegd. // fmt.Print ("Toegevoegd project" + proj + "aan de lijst.") // // Functie: staat // // Beschrijving: deze functie geeft de juiste uitvoer voor het wijzigen van de status. De staat // is eerst de tegengestelde van de huidige staat. // func state () // // Krijg de laatste status van het huidige project. // stateFile: = getTimeSheetDir () + "/laststate.txt" buf, _: = ioutil.ReadFile (stateFile) curState: = string (buf) // // Stel de eerste opdracht in op het tegenovergestelde van de huidige status. Op die manier // duwt de gebruiker eenvoudig terug naar schakelstanden. // 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 "," yes " , "", "") // // Print de XML-string. // fmt.Print (goAlfred.ToXML ()) // // Functie: project // // Beschrijving: met deze functie wordt een lijst met projecten gemaakt en worden de // weergegeven die lijken op de invoer. // func-project () // // Haal de projectnaam op vanaf de opdrachtregel. // proj: = GetCommandLineString () // // Stel onze standaardreeks in. // goAlfred.SetDefaultString ("Alfred Time Keeper: Sorry, geen overeenkomst ...") // // Download het nieuwste project. // latestproject: = GetCurrentProject () // // Verkrijg de lijst met projecten. // projecten: = make ([] string, MAXPROJECTS) projects = GetListOfProjects () // // De regexp-gesplitste instructie geeft één reeks meer dan werd gesplitst. De laatste // -reeks is een catchall. Het hoeft niet te worden opgenomen. // numproj: = len (projecten) - 1 // // Maak voor elk project een resultaatregel. Laat alles zien wat het huidige project is. // voor i: = 0; ik < 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]) // // Download het huidige project. // currentProject: = GetCurrentProject () // // Voer de juiste functie uit en druk de resultaten af. // fmt.Print (StopStartProject (currentProject, cmd)) // // Functie: GetCurrentProject // // Beschrijving: met deze functie wordt het huidige project opgehaald uit het // state-bestand. // func GetCurrentProject () string // // Download het huidige project. // Bestandsnaam: = getTimeSheetDir () + "/project.txt" buf, _: = ioutil.ReadFile (bestandsnaam) // // Converteer het huidige project naar een tekenreeks, knip het in en retourneer het. // return (strings.TrimSpace (string (buf))) // // Functie: SaveProject // // Beschrijving: deze functie slaat de opgegeven projectnaam op in het // huidige projectbestand. // // Inputs: // proj Naam van het nieuwe project // func SaveProject (proj string) // // Schrijf het nieuwe project. // Bestandsnaam: = getTimeSheetDir () + "/project.txt" err: = ioutil.WriteFile (Bestandsnaam, [] byte (proj), 0666) if err! = Nil fmt.Print ("Kan het projectbestand niet schrijven : "+ Bestandsnaam) os.Exit (1) // // Functie: StopStartProject // // Beschrijving: deze functie wordt gebruikt om de status voor het gegeven project in te stellen. // // Inputs: // currentProject Het project om de status van. // cmd Het start- of stopcommando. // func StopStartProject (currentProject string, cmd string) string // // Stel de resultaatreeks in. // resultStr: = "" currentState: = GetCurrentState () // // Is de huidige status hetzelfde als de nieuwe staat? // if strings.Contains (cmd, currentState) // // Het is al in die staat. Doe niets, maar geef een bericht. // resultStr = "Al" + cmd + "\ n" anders // // Oké, we kunnen doorgaan met het schrijven van de nieuwe staat in het // datum projectbestand. Open het bestand om te schrijven. // currentTime: = time.Now () Bestandsnaam: = generateTimeLogFileName (currentProject, currentTime) Fh, err: = os.OpenFile (Bestandsnaam, os.O_APPEND | os.O_WRONLY | os.O_CREATE, 0666) if err! = nil  // // Het bestand zou niet openen. Foutmelding. // fmt.Print ("Kon het gedateerde projectbestand niet openen:", Bestandsnaam, "\ n") os.Exit (1) // // Schrijf de nieuwe opdracht met de tijdstempel naar de buffer. // str: = fmt.Sprintf ("% d:% s \ n", currentTime.Unix (), cmd) _, err = io.WriteString (Fh, str) // // Verlies het bestand. // Fh.Close () // // Schrijf het bestand met de laatste staat met de nieuwe status. // ioutil.WriteFile (getTimeSheetDir () + "/ laststate.txt", [] byte (cmd), 0666) // // Vertel de gebruiker dat deze is ingesteld. // resultStr = currentProject + "is nu" + cmd // // Retourneer de resulterende tekenreeks. // return (resultStr) // // functie: GetCurrentState // // Beschrijving: deze functie krijgt de huidige status van het project. // func GetCurrentState () string // // Krijg de huidige status. // Bestandsnaam: = getTimeSheetDir () + "/laststate.txt" buf, err: = ioutil.ReadFile (Bestandsnaam) currentState: = "stop" als err == nil // // Converteer het huidige project naar een string en trim het. // currentState = strings.TrimSpace (string (buf)) return currentState // // Functie: generateTimeLogFileName // // Beschrijving: met deze functie wordt het tijdlogbestand gemaakt op basis van de projectnaam en // datum. // // Inputs: // proj Naam van het project // dt Betrokken datum // func generateTimeLogFileName (proj string, dt time.Time) string // // Genereer de juiste bestandsnaam op basis van de projectnaam en datum . // bestandsnaam: = getTimeSheetDir () + "/" + proj + "_" + dt.Format ("2006-01-02") + ".txt" return (bestandsnaam) 

Die code definieert alle functionaliteit van de Alfred Timekeeper. Het ontwerp van het programma is om verschillende functies uit te voeren op basis van een opdrachtbrief en opties die daarna worden ingesteld. Het krijgt de timesheet-directory van Alfred en maakt de projectbestanden en urenstaten naar behoefte.

Het compileren

Je moet het programma compileren voordat je het kunt gebruiken. De go-taal is geen geïnterpreteerde taal, maar een gecompileerde taal. Hierdoor kan het programma veel sneller worden uitgevoerd.

Typ in het terminalprogramma:

ga Timekeeper.go bouwen 
Compileren van Timekeeper.go

Als alles op zijn plaats is, zou u nu de Tijdwaarnemer programma in die map. Het is in rood hierboven. Als iets niet goed is gekopieerd en het compileren mislukt, zoek dan het opgegeven regelnummer op en vergelijk het met het bovenstaande. Of haal een nieuw exemplaar van de download die bij deze zelfstudie is meegeleverd.

Alfred-functies toevoegen

Als het programma klaar is, moet je het van Alfred bellen. Maak een keyword blokkeren met het trefwoord ingesteld op atk: addproject. Verbind het met een Voer het script uit blok en zet deze regel code:

./ TimeKeeper een "query" 

Allemaal Scripts uitvoeren blokken hier buiten moeten worden ingesteld om te worden uitgevoerd bash scripts en geen van de ontsnappingsopties die zijn ingesteld. Het bovenstaande script maakt het mogelijk om nieuwe projecten te maken. Gebruik dit om uw verschillende projecten te maken. Ik heb de projecten: Envato, CustomCT, en opdrachten gemaakt voor het werk dat ik doe.

Nu je projecten hebt, moet je er nu een instellen als het huidige project. Maak een Scriptfilter zoals hieronder:

Scriptfilter voor het selecteren van een project

Voeg een ... toe Voer het script uit blok erna erop met het volgende script:

./ Tijdwaarnemer c "query" 
Het project instellen

Nu kunt u het project instellen waaraan u wilt werken. Typ in de Alfred-prompt atk: project en een lijst met gemaakte projecten zou moeten verschijnen. Selecteer het gewenste project en het begint automatisch met de timing voor u.

Daarom, als u de tutorials project, er is een bestand met de naam Tutorials_2014-05-05.txt (dat wil zeggen, zolang je het op 5 mei 2014 hebt gemaakt). In dat bestand bevindt zich een tijdstempel, een dubbele punt en een begin uitspraak. Je hebt ook de project.txt bestand met het momenteel geselecteerde project, laststate.txt bestand met de laatste status (dat wil zeggen: begin of hou op), en de projects.txt bestand met een lijst met gemaakte projecten.

De timing is begonnen, maar nu moet je het stoppen. Maak een nieuw Scriptfilter blokkeren met het trefwoord ingesteld op atk: state en het script ingesteld op:

./ TimeKeeper s "query" 

Dat moet verbinden met een Voer het script uit blokkeren met het script ingesteld op:

./ TimeKeeper o "query" 

De s commando vertelt Timekeeper-programma om een ​​XML-uitvoer te genereren voor de volgende status. Het zal automatisch de eerste optie in de XML hebben om het tegenovergestelde van de huidige status te zijn.

Veranderen van timing staten

U kunt nu de status van timing van een project wijzigen atk: state. U kunt ook sneltoetsen maken om de timing te starten en te stoppen. Probeer dat alleen te doen. Je leert het nooit totdat je het probeert!

Een externe trigger toevoegen

U wilt mogelijk een extern programma om de status van tijdregistratie in te stellen. Maak daarom een Externe trigger blokkeren zoals getoond. Verbind dit blok met het vorige Voer het script uit blok.

Een externe trigger toevoegen - configuratie

De Voorbeeldcode onderaan kan worden uitgevoerd door een AppleScript-bewust programma om te activeren start Stop acties voor het huidige project. Als u de tekst vervangt test met hou op, het stopt de timing. Als u de tekst vervangt test met begin, het zal de timing beginnen. Gebruikt met ControlPlane, u kunt een regel maken om de timing uit te schakelen wanneer de computer slaapt en de timing hervat wanneer de computer wordt geactiveerd.

Nu u de tijd start en stopt, moet u de bestede tijd bekijken. Maak een keyword blokkeren met atk: stroom. Verbind het met een Voer het script uit blokkeer met dit script:

echo './Technicus b'; 

Verbind het met de Kennisgeving blok.

Current Time Command

Wanneer je rent atk: stroom in Alfred prompt krijgt u de huidige tijd besteed aan het project en de huidige staat.

Tweede computer

Als je een andere computer hebt, stel dan Alfred in om te delen via Dropbox. Na het instellen worden al uw werkstromen automatisch bijgewerkt van de ene computer naar de andere.

Alfred-synchronisatie instellen

Selecteer de Stel de synchronisatiemap in om synchronisatie via Dropbox in te stellen en volg de aanwijzingen. Gebruik de opdracht op de tweede computer atk: setdir om de timesheet-map in te stellen die u in Dropbox hebt gemaakt. De twee systemen kunnen nu projecttimings starten en stoppen. Zorg ervoor dat Dropbox volledig is gesynchroniseerd tussen statuswijzigingen.

Conclusie

Dat is de basis van de Alfred Timekeeper. De workflow die bij de download wordt geleverd, is de volledige versie met andere functies. U begrijpt nu hoe u uw eigen tijdmanagementsysteem kunt maken dat schaalbaar is om op meerdere computers te gebruiken met Dropbox en dat geen computerbronnen in beslag neemt. 

Aangezien ik dit elke dag gebruik, zal ik meer functies toevoegen, zoals een webinterface om de timesheets grafisch te bekijken. Als je andere functies kunt bedenken, probeer ze dan zelf toe te voegen! Dat is het plezier van het werken met Alfred-workflows.