Seguir el tiempo del proyecto con Alfred Timekeeper

Lo que vas a crear

Alfred Time Keeper

Muchas personas hacen malabares con múltiples proyectos con diferentes horarios. Desde aplicaciones web hasta programas dedicados, ya hay varias formas de llevar un registro del tiempo dedicado a un proyecto. La mayoría requiere un servicio de red y / o un programa para estar funcionando todo el tiempo. A menudo esto no es práctico.

Alfred Timekeeper funciona de manera similar a un sistema de mantenimiento de tiempo de tarjetas perforadas: guarda una marca de tiempo cuando comienza y deja de funcionar. Como solo registra las marcas de tiempo, un programa o servicio web no siempre está abierto.

En este tutorial, asumiré que ya estás familiarizado con la escritura de flujos de trabajo en Alfred. De lo contrario, consulte estos tutoriales: Alfred para principiantes, intermedios, usuarios avanzados y depuración de Alfred.

Diseño general

Muchas personas trabajan con diferentes computadoras en diferentes lugares. Eso hace que el seguimiento de los proyectos y la gestión del tiempo sea mucho más difícil. Al utilizar Dropbox, toda la información de gestión de proyecto y tiempo se sincroniza automáticamente.

Este enfoque requiere el mantenimiento de toda la información en archivos y no en la memoria de la computadora. Esta restricción requiere el uso de dos acuerdos de almacenamiento de datos: directorio local de la información utilizada por el programa de ese sistema solamente, y una directorio sincronizado eso se comparte con cada computadora conectada a ella.

El almacenamiento local contiene la referencia al directorio sincronizado y al editor para editar las hojas de tiempo. Estos archivos están en la ubicación del directorio de datos de Alfred.

El directorio sincronizado mantiene todas las hojas de tiempo, listas de proyectos, el último estado conocido de información de grabación y la información de la zona horaria. Eso estará en una ubicación de Dropbox. Se puede usar cualquier sistema de sincronización del sistema de archivos, es que ya tengo Dropbox.

Creando el flujo de trabajo

En Alfred, crea un nuevo flujo de trabajo llamado Alfred Timekeeper.

Creando el flujo de trabajo

En este nuevo flujo de trabajo, necesita crear un Filtro de archivos eso solo listará directorios.

Establecer comando de directorio de parte de horas

Puede configurar el Tipos de archivo arrastrando un directorio desde Descubridor al Tipos de archivo zona. Selecciona el Alcance de búsqueda al directorio que contiene su cuenta DropBox.

Agrega un Ejecutar guión bloque después de este bloque, deseleccionando todas las opciones de escape. A ese bloque, agregue este script:

######################### # Contants. ######################### VPREFS = "$ HOME /Library/Caches/com.runningwithcrayons.Alfred-2/Workflow Data /" NVPREFS = "$ HOME / Library / Application Support / Alfred 2 / Workflow Data /" ############################### ############################################### # Leer el bundleid de info.plist ####################################### ################################### getBundleId () / usr / libexec / PlistBuddy -c "Imprimir: bundleid "" info.plist " ########################################## #################################### # Obtenga los datos del flujo de trabajo ######## ################################################## #################### getDataDir () local BUNDLEID = $ (getBundleId) echo "$ NVPREFS $ BUNDLEID" if [! -d "$ (getDataDir)"]; entonces mkdir -p "$ (getDataDir)"; toque "$ (getDataDir) /dir.txt"; toque "$ (getDataDir) /editor.txt"; fi # Almacena la información del directorio. echo "query"> "$ (getDataDir) /dir.txt"; # Dile al usuario. echo "Establecer directorio en 'consulta'."; 

Este script comprueba que el directorio de datos esté allí. Si no está allí, crea el directorio y los archivos utilizados para el flujo de trabajo. Toma la entrada en el consulta macro y lo coloca en el dir.txt archivo en el directorio de datos. A continuación, notifica al usuario de la acción..

Conecta el Ejecutar guión bloque a un bloque de notificación. Todos Ejecutar guión los bloques de aquí en adelante deben conectarse a este bloque de notificación. Establece su salida para ser el consulta macro y establecer el Solo mostrar si se pasa en argumento tiene contenido.

Una vez guardado, configure el directorio de la hoja de tiempo. Dentro del directorio de Dropbox, cree un directorio para las hojas de tiempo y use el atk: setdir comando para establecer ese directorio. Ahora estás ejecutando un programa de cronometraje de sistema múltiple!

Esa es la rutina de configuración básica para el flujo de trabajo. Antes de abordar el programa principal, necesita configurar el entorno de trabajo.

Configuración del entorno Go

La forma más fácil de instalar el lenguaje de programación go es mediante Homebrew. Si no has instalado Homebrew sin embargo, el tutorial Homebrew Demystified: Ultimate Package Manager de OS X te mostrará cómo.

En una terminal, escriba:

instalar cerveza 

En el directorio de inicio, crea el directorio. ir. El idioma de ir almacenará todas las bibliotecas descargadas allí. Añadir a la .Bashrc archivo y / o .zshrc archiva esta linea:

exportar GOPATH = "/ Usuarios //ir" 

Si está usando pescado, agregue esto a la config.fish expediente:

set -xg GOPATH "/ Usuarios //ir" 

Después de volver a cargar el shell, puede instalar la biblioteca goAlfred escribiendo:

ve a github.com/raguay/goAlfred 

Esta biblioteca facilita mucho el uso del lenguaje go con Alfred. Creará los directorios al área de almacenamiento de datos para los flujos de trabajo Alfred y hará que la lista XML sea necesaria en Filtros de script.

Timekeeper.go

Para crear el archivo de programa principal, debe ir al directorio para el flujo de trabajo. Abre el Ejecutar guión bloquear.

Abrir el directorio de flujo de trabajo

Haga clic en el Abrir carpeta de flujo de trabajo botón en la parte inferior de la Guión: zona. Esto abre el directorio de flujo de trabajo en Descubridor (o Pionero si lo tienes). Para abrir el directorio en un shell de terminal, puede usar el Buscador de terminales de flujo de trabajo de Alfred para abrir un directorio Finder o Path Finder en una sesión de terminal (o iTerm).

Creando el archivo de programa en la terminal

Una vez en el programa terminal, escriba:

toque Timekeeper.go 

Abra ese archivo en el editor de su elección. Una vez abierto, ponga este código en:

package main // // Program: TimeKeeper.go // // Description: Este programa ejecuta la lógica de retroalimentación para seleccionar el estado de activación / desactivación para // el proyecto cronometrado actualmente. // // // Importar las bibliotecas que usamos para este programa. // importar ("fmt" "github.com/raguay/goAlfred" "io" "io / ioutil" "os" "regexp" "strconv" "strings" "time") // // Configuración y constantes que se utilizan . // // MAXPROJECTS Este es el número máximo de proyectos permitidos. // TSDir Esto mantiene el nombre del directorio para las hojas de tiempo. Es un camino completo. // const (MAXPROJECTS int = 20) var TSDir = "" // // Función: main // // Descripción: Esta es la función principal del programa TimeKeeper. Toma la línea de comando // y la analiza para la funcionalidad adecuada. // func main () if len (os.Args)> 1 switch os.Args [1] [0] case 'm': // // atk: month // SystemViewMonth () case 'w': // // atk: week // SystemViewWeek () caso 't': // // atk: current // SystemViewDate () caso 'r': // // atk: remove // ​​RemoveProject () case 'c' : // // atk: project // ChangeProject () caso 'b': // // atk: current // SystemViewDay () case 'a': // atk: addproject // AddProject () case 'o ': // // atk: state // StopStart () caso' p ': // // Se usa para atk: project fileter // project () case' T ': // // atk: time // SystemAllProjects () case 's': fallthrough default: // // Se usa para el filtro de script en atk: state // state () // // Function: getTimeSheetDir // // Description: Esta función se usa para almacenar en caché una copia del directorio // hoja de hora y entregarlo en la devolución. // func getTimeSheetDir () string if strings.Contains ("", TSDir) Filename: = goAlfred.Data () + "/dir.txt" buf, err: = ioutil.ReadFile (Filename) si err == nil // // Convierta la ruta del directorio en una cadena y recórtela. // TSDir = strings.TrimSpace (string (buf)) // // Regresa el directorio a las hojas de tiempo. // return (TSDir) // // Función: SystemAllProjects // // Descripción: Esta función mostrará al terminal la hora de todos los proyectos en // el día que aparece en la línea de comandos a continuación. // func SystemAllProjects () // // Obtenga la fecha actual en caso de que no haya una en la línea de comando. // tm: = time.Now () if len (os.Args)> 2 if strings.Contains ("today", os.Args [2]) // // Fecha de hoy. // tm = time.Now () else if strings.Contains ("yesterday", os.Args [2]) // // Ayer es hoy menos un día. // tm = time.Now () tm = tm.AddDate (0, 0, -1) else // // Parse la cadena de fecha dada. // tm, _ = time.Parse ("2006-Jan-02", os.Args [2]) // // Obtenga la lista de nombres de proyectos. // proj: = GetListOfProjects () // // Para cada proyecto, obtenga el tiempo empleado en el mismo día. // numproj: = len (proj) - 1 para i: = 0; yo < 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]) // // Devuelve la cadena. // return (clstring) // // Función: AddProject // // Descripción: Esta función agregará un nuevo proyecto a la lista de proyectos actuales. // func AddProject () // // Obtenga el nombre del proyecto desde la línea de comandos. // proj: = GetCommandLineString () // // Crea el nombre del archivo que contiene todos los proyectos. // projectFile: = getTimeSheetDir () + "/projects.txt" Fh, err: = os.OpenFile (projectFile, os.O_APPEND | os.O_WRONLY | os.O_CREATE, 0666) si err = = os.Create (projectFile) if err! = nil // // El archivo no se abrirá. Error de salida // fmt.Print ("No se pudo abrir el archivo de proyectos:", projectFile, "\ n") os.Exit (1) // // Escriba el nuevo comando con la marca de tiempo en el búfer. // _, err = io.WriteString (Fh, proj + "\ n") // // Pierde el archivo. // Fh.Close () // // Dígale al usuario que el proyecto está agregado. // fmt.Print ("Proyecto agregado" + proj + "a la lista.") // // Función: estado // // Descripción: Esta función proporciona la salida adecuada para cambiar el estado. El estado // primero es el opuesto al estado actual. // func state () // // Obtiene el último estado del proyecto actual. // stateFile: = getTimeSheetDir () + "/laststate.txt" buf, _: = ioutil.ReadFile (stateFile) curState: = string (buf) // // Establezca el primer comando al contrario del estado actual. De esa manera // el usuario simplemente presiona regresar a los estados de alternancia. // if strings.Contains (curState, "start") goAlfred.AddResult ("stop", "stop", "stop", ",, icon.png", "yes", "", "") .AddResult ("start", "start", "start", ",, icon.png", "yes", "", "") else goAlfred.AddResult ("start", "start", " start "," "," icon.png "," yes "," "," ") goAlfred.AddResult (" stop "," stop "," stop ",",, icon.png "," yes " , "", "") // // Imprima la cadena xml. // fmt.Print (goAlfred.ToXML ()) // // Función: proyecto // // Descripción: Esta función crea una lista de los proyectos y muestra los // similares a la entrada. // func project () // // Obtiene el nombre del proyecto desde la línea de comando. // proj: = GetCommandLineString () // // Establece nuestra cadena predeterminada. // goAlfred.SetDefaultString ("Alfred Time Keeper: Lo siento, no coincide ...") // // Obtenga el último proyecto. // latestproject: = GetCurrentProject () // // Obtenga la lista de proyectos. // projects: = make ([] string, MAXPROJECTS) projects = GetListOfProjects () // // La instrucción de división de expresiones regulares da una cadena más de la que se dividió. La última // cadena es un catchall. No necesita ser incluido. // numproj: = len (proyectos) - 1 // // Para cada proyecto, cree una línea de resultados. Mostrar todo poner el proyecto actual. // para i: = 0; yo < 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]) // // Obtener el proyecto actual. // currentProject: = GetCurrentProject () // // Ejecuta la función apropiada e imprime los resultados. // fmt.Print (StopStartProject (currentProject, cmd)) // // Función: GetCurrentProject // // Descripción: Esta función recuperará el proyecto actual del archivo de estado //. // func cadena GetCurrentProject () // // Obtener el proyecto actual. // Nombre de archivo: = getTimeSheetDir () + "/project.txt" buf, _: = ioutil.ReadFile (Nombre de archivo) // // Convierta el proyecto actual en una cadena, recórtelo y devuélvalo. // return (strings.TrimSpace (string (buf))) // // Función: SaveProject // // Descripción: Esta función guardará el nombre del proyecto dado en // el archivo del proyecto actual. // // Entradas: // proj Nombre del nuevo proyecto // func SaveProject (cadena de proyecto) // // Escriba el nuevo proyecto. // Nombre de archivo: = getTimeSheetDir () + "/project.txt" err: = ioutil.WriteFile (Nombre de archivo, [] byte (proj), 0666) si err! = Nil fmt.Print ("No se puede escribir el archivo de proyecto : "+ Nombre de archivo) os.Exit (1) // // Función: StopStartProject // // Descripción: esta función se usa para establecer el estado del proyecto dado. // // Entradas: // currentProject El proyecto para efectuar el estado de. // cmd El comando de inicio o parada. // func StopStartProject (currentProject string, cmd string) string // // Configure la cadena de resultados. // resultStr: = "" currentState: = GetCurrentState () // // ¿El estado actual es el mismo que el nuevo estado? // if strings.Contains (cmd, currentState) // // Ya está en ese estado. No hagas nada, solo da un mensaje. // resultStr = "Ya" + cmd + "\ n" else // // Bien, podemos continuar escribiendo el nuevo estado en el // archivo de proyecto con fecha. Abra el archivo para escribir. // currentTime: = time.Now () Nombre de archivo: = generateTimeLogFileName (currentProject, currentTime) Fh, err: = os.OpenFile (Nombre de archivo, os.O_APPEND | os.O_WRONLY | os.O_CREATE, 0666) si err! = nil  // // El archivo no se abriría. Error de salida // fmt.Print ("No se pudo abrir el archivo de proyecto con fecha:", Nombre de archivo, "\ n") os.Exit (1) // // Escriba el nuevo comando con la marca de tiempo en el búfer. // str: = fmt.Sprintf ("% d:% s \ n", currentTime.Unix (), cmd) _, err = io.WriteString (Fh, str) // // Pierde el archivo. // Fh.Close () // // Escriba el archivo de último estado con el nuevo estado. // ioutil.WriteFile (getTimeSheetDir () + "/ laststate.txt", [] byte (cmd), 0666) // // Dígale al usuario que está configurado. // resultStr = currentProject + "is now" + cmd // // Devuelve la cadena resultante. // return (resultStr) // // function: GetCurrentState // // Description: Esta función obtiene el estado actual del proyecto. // func cadena GetCurrentState () // // Obtiene el estado actual. // Nombre de archivo: = getTimeSheetDir () + "/laststate.txt" buf, err: = ioutil.ReadFile (Nombre de archivo) currentState: = "stop" si err == nil // // Convertir el proyecto actual en una cadena y recórtalo // currentState = strings.TrimSpace (string (buf)) return currentState // // Función: generateTimeLogFileName // // Descripción: esta función crea el archivo de registro de tiempo basado en el nombre y la fecha del proyecto. // // Entradas: // proj Nombre del proyecto // fecha de dt en cuestión // func generateTimeLogFileName (proj string, dt time.Time) string // // Genere el nombre de archivo adecuado según el nombre y la fecha del proyecto . // nombre de archivo: = getTimeSheetDir () + "/" + proj + "_" + dt.Format ("2006-01-02") + ".txt" return (nombre de archivo) 

Ese código define toda la funcionalidad del Alfred Timekeeper. El diseño del programa es hacer diferentes funciones basadas en una letra de comando y parámetros de opciones después de él. Obtendrá el directorio de la hoja de tiempo de Alfred y creará los archivos del proyecto y las hojas de tiempo según sea necesario.

Compilando

Tienes que compilar el programa antes de poder usarlo. El lenguaje go no es un lenguaje interpretado, sino un lenguaje compilado. Esto permite que el programa se ejecute mucho más rápido..

En el programa de terminal, escriba:

Ve a construir Timekeeper.go 
Compilando Timekeeper.go

Si todo está en su lugar correctamente, ahora debería tener el Cronometrador programa en ese directorio. Está en rojo arriba. Si algo no se copió correctamente y la compilación falla, busque el número de línea dado y compárelo con el anterior. O bien, obtenga una copia nueva de la descarga proporcionada con este tutorial..

Añadiendo funciones de Alfred

Con el programa terminado, necesitas llamarlo de Alfred. Crear un Palabra clave bloque con la palabra clave establecida en atk: addproject. Conéctalo a un Ejecutar guión Bloquea y coloca esta línea de código:

./ TimeKeeper un "consulta" 

Todos Ejecutar scripts Los bloques de aquí en adelante deben configurarse para correr. golpetazo scripts y ninguna de las opciones de escape establecidas. El script anterior permite crear nuevos proyectos. Usa esto para crear tus diferentes proyectos. Tengo los proyectos: Envato, CustomCT, y Las misiones creado para el trabajo que hago.

Ahora que tiene proyectos, ahora necesita establecer uno como el proyecto actual. Crear un Filtro de script como a continuación:

Filtro de script para seleccionar un proyecto

Agrega un Ejecutar guión Bloquee después con el siguiente script:

./ Timekeeper c "consulta" 
Configurando el proyecto

Ahora, puede configurar el proyecto en el que desea trabajar. En el aviso de Alfred, escriba atk: proyecto y debería aparecer una lista de los proyectos creados. Seleccione el proyecto que desea e iniciará automáticamente el cronometraje para usted..

Por lo tanto, si seleccionó la Tutoriales proyecto, hay un archivo llamado Tutorials_2014-05-05.txt (es decir, siempre que lo haya creado el 5 de mayo de 2014). Dentro de ese archivo hay una marca de tiempo, dos puntos y una comienzo declaración. También tendrás la proyecto.txt archivo con el proyecto seleccionado actualmente, laststate.txt archivo con el último estado (es decir: comienzo o detener), y el proyectos.txt archivo con una lista de proyectos creados.

El tiempo ha comenzado, pero ahora necesitas detenerlo. Crear un nuevo Filtro de script bloque con la palabra clave establecida en atk: estado y el script configurado para:

./ TimeKeeper s "consulta" 

Eso debería conectarse a un Ejecutar guión bloque con el script establecido en:

./ TimeKeeper o "consulta" 

los s el comando le dice al programa Timekeeper que genere una salida XML para el siguiente estado. Tendrá automáticamente la primera opción en el XML para ser el opuesto al estado actual.

Estados de tiempo cambiantes

Ahora puede cambiar el estado de sincronización de un proyecto con atk: estado. También puede crear teclas de acceso rápido para iniciar y detener el tiempo. Trate de hacer eso por su cuenta. Nunca aprendes hasta que lo intentas.!

Añadiendo un disparador externo

Es posible que desee un programa externo para establecer el estado de grabación de tiempo. Por lo tanto, crea un Gatillo externo bloque como se muestra. Conecta este bloque al anterior. Ejecutar guión bloquear.

Adición de un activador externo - Configuración

los Código de muestra en la parte inferior se puede ejecutar con cualquier programa compatible con AppleScript para activar iniciar / detener Acciones sobre el proyecto actual. Si reemplazas el texto prueba con detener, se detendrá el tiempo. Si reemplazas el texto prueba con comienzo, se iniciará el tiempo. Usado con Plano de control, puede crear una regla para apagar el tiempo cuando la computadora está inactiva y reanudar el tiempo cuando la computadora se despierta.

Ahora que está comenzando y deteniendo el tiempo, necesita ver el tiempo empleado. Crear un Palabra clave bloque con atk: actual. Conéctalo a un Ejecutar guión bloque con este script:

echo './Timekeeper b'; 

Conectarlo a la Notificación bloquear.

Comando de hora actual

Cuando corres atk: actual en el indicador de Alfred, obtendrá el tiempo actual empleado en el proyecto y el estado actual.

Segunda computadora

Si tienes otra computadora, configura Alfred para compartir en Dropbox. Una vez configurado, todos sus flujos de trabajo se actualizarán automáticamente de una computadora a otra.

Configurando Alfred Syncing

Selecciona el Establecer carpeta de sincronización para configurar la sincronización a través de Dropbox y siga las instrucciones. En la segunda computadora, use el comando atk: setdir para configurar el directorio de la hoja de tiempo que creó en Dropbox. Los dos sistemas ahora pueden iniciar y detener los tiempos del proyecto. Asegúrate de que Dropbox esté completamente sincronizado entre los cambios de estado.

Conclusión

Eso es lo básico de Alfred Timekeeper. El flujo de trabajo empaquetado con la descarga es la versión completa con otras características. Ahora entiende cómo crear su propio sistema de administración del tiempo que es escalable para usar en múltiples computadoras usando Dropbox y no ocupa recursos de la computadora. 

Como lo uso todos los días, agregaré más funciones, como una interfaz web para ver gráficamente las hojas de tiempo. Si puede encontrar otras funciones, ¡intente agregarlas usted mismo! Eso es lo divertido de trabajar con flujos de trabajo Alfred.