Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

[script] LifeLogger v0.85 (2007-02-12)


  • Please log in to reply
18 replies to this topic
Ace_NoOne
  • Members
  • 299 posts
  • Last active: May 02 2008 08:19 AM
  • Joined: 10 Oct 2005
Aloha,

After quite a long time of more-or-less forced abstinence, I've written a little AHK script again. It's not completely finished yet, but it's only missing comfort functions, and I thought I'd share it.

The idea's inspired by a Lifehacker posting (and a particular comment) - my adaptiation is meant to help you logging your life!
Sounds somewhat scary, eh - well, I created it to better keep track of important events (e.g. renewed magazine subscriptions, purchases etc.) and to quickly record things that pop into my mind (e.g. ideas - but also things like vocabulary or other stuff I pick up).

Here's how it works: Assign a keyboard combo (by editing a Windows shortcut to the EXE; e.g. [CTRL]+[ALT]+[L]) that starts the script, and it will present you with a simple GUI consisting of three input fields; Timestamp, Description and Tag(s).
The timestamp is filled in automatically, the description contains the actual item and the last column contains tags (duh!) which are meant to facilitate retrieval later on.
These entries are stored in a CSV-like file - here's a random example of what that might look like:
Timestamp        || Description                    || Tag(s)
2006-11-03 14:49 || renewed Newsweek subscription  || magazine money purchase
2006-11-05 18:23 || LifeLogger: tag selection list || dev
2006-11-06 15:30 || ahead of the pack              || vocab:phrase
However, I have to admit that I myself don't really have the discipline/memory to always log everything I'd want to, which kinda defeats the purpose. Also, it can be a bit of a hassle to create (and stick to) a consistent vocabulary for the tagging.

Anyways, enough of the description, let the code talk (scroll down for the required INI):
/*
LifeLogger v0.85
 by FND

Simple interface to quickly create short entries in a CSV-like log file.

Inspired by QuickLoggerPlus by Kirk Friggstad, which is based on QuickLogger
by Gina Trapani, which in turn is based on (VBS) code by Joshua Fitzgerald.
*/

/*
ToDo:
- add option to create backups
- add selection list for (recently/frequently used) tags
- add options menu
- option to use different tag files for each log file
- integrate xSV Editor (external module => pass column separator)
- add encryption (optional); per-entry basis (problematic!?)
- add option to auto-rotate filenames (new file each day/week/month/year)
*/

/*
Changelog
¯¯¯¯¯¯¯¯¯
# v0.85 (2007-02-12)
* removed tray icon
* added command line switch "-l" for specifying active log file
* made ESC hotkey context-sensitive (triggered only when script window is active)
* re-arranged configuration file
* fixed default settings: time now in 24-hour format, Windows mode for linefeeds

# v0.8 (2006-11-06)
* first version based on QuickLogger++ (unreleased adaptation of QuickLoggerPlus)
* added tagging functionality to the original concept
*/

/*
********** settings, variable declarations **********
*/

#SingleInstance Force
#NoEnv
#NoTrayIcon
OnExit, quit

programName = LifeLogger
programVersion = 0.85
programFullName = %programName% v%programVersion%
programAuthor = FND

configFile = LifeLogger.ini

/*
********** auto-execute section **********
*/

; getSettings
GoSub, getSettings
; process command line parameters
GoSub, getParams
; get current time
GoSub, getTime
; construct GUI
GoSub, showGUI
; define this script's windows (required for context-sensitive hotkeys)
GroupAdd, thisScript, %programName%
; end of auto-execute section
Return

/*
********** hotkeys **********
*/

; [ESC]: terminate script
#IfWinActive, ahk_group thisScript
Esc::
	Suspend ; exempt from suspension
	GoSub, quit
Return

/*
********** subroutines **********
*/

; process command line parameters
getParams:
	Loop, %0% ; for each command line parameter
	{
	    ; "-l": active log file
		If (%A_Index% = "-l")
			param := A_Index + 1
			logFile := %param%
	}
Return

; construct GUI
showGUI:
	; menu bar
	Menu, fileMenu, Add, Select active &log, logFileSelect
	Menu, fileMenu, Add, Show &active log, logFileOpen
	Menu, fileMenu, Add
	Menu, fileMenu, Add, E&xit, quit
	Menu, HelpMenu, Add, &About, about
	Menu, menuBar, Add, &File, :fileMenu
	Menu, menuBar, Add, &?, :HelpMenu
	Gui, Menu, menuBar
	; GUI items
	Gui, Font, Bold
	Gui, Add, Text, x6 y7 w100, %timestampHeading%
	Gui, Font, Norm
	Gui, Add, Edit, x6 y27 w100 vTimestamp, %now%
	Gui, Font, Bold
	Gui, Add, Text, x116 y7 w300, %descHeading%
	Gui, Font, Norm
	Gui, Add, Edit, x116 y27 w300 vDesc,
	Gui, Font, Bold
	Gui, Add, Text, x426 y7 w150, %tagsHeading%
	Gui, Font, Norm
	Gui, Add, Edit, x426 y27 w150 vTags,
	Gui, Add, Button, x366 y67 w100, Cancel
	Gui, Add, Button, x476 y67 w100 default, OK
	Gui, Show ,, %programName%
	; skip timestamp field
	If (skipTimestamp = True)
	{
		Send, {Tab} ; DEBUG: dirty hack!?
	}
Return

ButtonOK:
	; save inputs
	Gui, Submit
	; trim leading and trailing spaces
	timestamp = %timestamp%
	desc = %desc%
	tags = %tags%
	; write to log file
	GoSub, writeLog
	; terminate script
	GoSub, quit
Return

logFileSelect:
	FileSelectFile, logFile, 2, %A_WorkingDir%
		, Please specify the name of the file to write log entries to.
Return

logFileOpen:
	IfExist, %logFile%
		Run, %logFile%
	Else
		MsgBox, Log file does not exist.
Return

ButtonCancel:
GuiClose:
	GoSub, quit
Return

; write to log file
writeLog:
	; check for invalid chars
	checkValidity(timestamp, "Timestamp")
	checkValidity(desc, "Description")
	checkValidity(tags, "Tag")
	; create log file with column headings if it doesn't exist already
	IfNotExist, %logFile%
		FileAppend
			, % timestampHeading . separator . descHeading . separator . tagsHeading . "`n"
			, %lfModifier%%logFile%
	; write to file
	FileAppend
		, % timestamp . separator . desc . separator . tags . "`n"
		, %lfModifier%%logFile%
Return

; get current time
getTime:
	If (useUTC = True)
	{
		FormatTime, now, %A_NowUTC%, %timeFormat%
	}
	Else
	{
		FormatTime, now, %A_Now%, %timeFormat%
	}
Return

; read user settings
getSettings:
	; create config file if it does not exist yet
	IfNotExist, %configFile%
		GoSub, writeSettings
	; read settings from file
	IniRead, logFileBase, %configFile%, logFiles, logFileBase
	IniRead, logFileExt, %configFile%, logFiles, logFileExt
	IniRead, tagFileBase, %configFile%, logFiles, tagFileBase
	IniRead, tagFileExt, %configFile%, logFiles, tagFileExt
	IniRead, skipTimestamp, %configFile%, interface, skipTimestamp
	IniRead, unixMode, %configFile%, CsvFormat, unixMode
	IniRead, useUTC, %configFile%, CsvFormat, useUTC
	IniRead, timeFormat, %configFile%, CsvFormat, timeFormat
	IniRead, separator, %configFile%, CsvFormat, separator ; DEBUG: filter potentially problematic chars (e.g. "`")!?
	IniRead, timestampHeading, %configFile%, columnHeadings, timestamp
	IniRead, descHeading, %configFile%, columnHeadings, desc
	IniRead, tagsHeading, %configFile%, columnHeadings, tags
	; convert True/False strings to actual boolean values
	stringToBoolean(skipTimestamp)
	stringToBoolean(unixMode)
	stringToBoolean(useUTC)
	; process settings
	logFile = %logFileBase%.%logFileExt%
	tagFile = %tagFileBase%.%tagFileExt%
	If (unixMode = True)
		lfModifier = * ; use Unix mode for linefeeds (LF)
	Else
		lfModifier = ; use Windows mode for linefeeds (CR+LF)
Return

; write user settings - DEBUG: to do (currently just for initialization)
writeSettings:
	IniWrite, LifeLogger, %configFile%, logFiles, logFileBase
	IniWrite, log, %configFile%, logFiles, logFileExt
	IniWrite, tags, %configFile%, logFiles, tagFileBase
	IniWrite, lst, %configFile%, logFiles, tagFileExt
	IniWrite, True, %configFile%, interface, skipTimestamp
	IniWrite, False, %configFile%, CsvFormat, unixMode
	IniWrite, True, %configFile%, CsvFormat, useUTC
	IniWrite, yyyy-MM-dd HH:mm, %configFile%, CsvFormat, timeFormat
	IniWrite, |, %configFile%, CsvFormat, separator
	; log file format
	IniWrite, Timestamp, %configFile%, columnHeadings, timestamp
	IniWrite, Description, %configFile%, columnHeadings, desc
	IniWrite, Tag(s), %configFile%, columnHeadings, tags
Return

; check for invalid chars
checkValidity(ByRef var, varTitle)
{
	Global separator
	Global programName
	If var Contains %separator%
	{
		MsgBox, 0, %programName%,
			( LTrim
				Error: %varTitle% contains column separator.
				Respective characters will be removed automatically.
			)
		cleanse(var, "")
	}
}

; remove potentially problematic chars
cleanse(ByRef string, cleanChar)
{
	; remove column separators
	Global separator
	StringReplace, string, string, %separator%, %cleanChar%, All
}

; convert True/False strings to actual boolean values
stringToBoolean(ByRef var)
{
	If var = True
		var := True
	Else
		var := False
}

; show info message
about:
	MsgBox, 64, %programFullName%,
	( LTrim
		%programFullName%
		%A_Space%by %programAuthor%

		Simple interface to quickly create short entries in a CSV-like log file.

		Inspired by QuickLoggerPlus by Kirk Friggstad, which is based on QuickLogger
		by Gina Trapani, which in turn is based on (VBS) code by Joshua Fitzgerald.

		Use [ESC] to terminate the program.
	)
Return

; terminate script
quit:
	; terminate script
	ExitApp
Return

Let me know what you think of the idea and the implementation, respectively.

Update: v0.85 (2007-02-12) released

mc
  • Members
  • 2 posts
  • Last active: Oct 03 2011 08:32 PM
  • Joined: 25 Jan 2006
Nice script!

...
; read user settings
getSettings:
	; create config file if it does not exist yet
	IfNotExist, %logFile%
	    GoSub, writeSettings
	; read settings from file
	IniRead, logFileBase, %configFile%, logFile, logFileBase

shouldn't that be
IfNotExist, %configFile%
:?:

mc

Ace_NoOne
  • Members
  • 299 posts
  • Last active: May 02 2008 08:19 AM
  • Joined: 10 Oct 2005
Of course not, you ignorant fool - can't you appreciate some creativity?
Translation: It's been fixed, thanks for letting me know! :)

polyethene
  • Administrators
  • 5511 posts
  • Last active: Apr 23 2014 11:38 PM
  • Joined: 26 Oct 2012
CSV!? I'm disappointed, I thought you would've used XML with W3C compliant schemas, a dtd and a binding summery rdf.
Translation: simple and easy, a DateTime control would be good though :)

Ace_NoOne
  • Members
  • 299 posts
  • Last active: May 02 2008 08:19 AM
  • Joined: 10 Oct 2005
LOL Titan, I actually did think about using XML - but came to the conclusion that it'd be overkill for this project. In fact, *SV is pretty much the perfect format for this kinda thing.
Thanks for recognizing my nerdiness though! :)

As for the DateTime control, I think that's a good idea.
However, the timestamp should actually not be edited manually at all (ideally that is), at least according to the original concept...

polyethene
  • Administrators
  • 5511 posts
  • Last active: Apr 23 2014 11:38 PM
  • Joined: 26 Oct 2012
Oh ok. Well anyway one things for sure, CSV is way easier to parse:
ini = LifeLogger.ini

IniRead, f, %ini%, logFile, logFileBase, LifeLogger

IniRead, e, %ini%, logFile, logFileExt, log

f = %f%.%e%

IniRead, s, %ini%, CsvFormat, separator, |

IniRead, t, %ini%, CsvFormat, timestamp, Timestamp

IniRead, d, %ini%, CsvFormat, desc, Description

IniRead, g, %ini%, CsvFormat, tags, Tag(s)

Gui, 2:Default

Gui, 2:+ToolWindow +LabelViewer

Gui, Add, ListView, w350 r7, %t%|%d%|%g%

Parse:

Loop, Read, %f%

	Loop, Parse, A_LoopReadLine, %s%

		If A_Index = 3

			LV_Add("", v1, v2, A_LoopField)

		Else v%A_Index% = %A_LoopField%

LV_Delete(1)

Loop, 3

	LV_ModifyCol(A_Index, "AutoHdr")

Gui, Show, , LifeLogger Viewer

Return

ViewerEscape:

ViewerClose:

ExitApp


Ace_NoOne
  • Members
  • 299 posts
  • Last active: May 02 2008 08:19 AM
  • Joined: 10 Oct 2005
The coding monkey strikes again!
Nicely done, but I'm missing the ability to edit each field...[/challenge]

polyethene
  • Administrators
  • 5511 posts
  • Last active: Apr 23 2014 11:38 PM
  • Joined: 26 Oct 2012

Nicely done, but I'm missing the ability to edit each field...[/challenge]

<?xml version="1.0" encoding="iso-8859-1"?>

<soap:Envelope xml:lang="en" xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">

  <soap:Body xmlns:challenge="http://purl.org/ahk/ownage#">

    <challenge:instance>

      <challenge:answer>[color=darkred]bring it on!!1[/color]</challenge:answer>

      <challenge:notes>[color=darkred]the following example can only change the description value :/[/color]</challenge:notes>

      <challenge:code type="application/ahk">

      <![CDATA[

[color=#666666]        ini = LifeLogger.ini

        IniRead, f, %ini%, logFile, logFileBase, LifeLogger

        IniRead, e, %ini%, logFile, logFileExt, log

        f = %f%.%e%

        IniRead, s, %ini%, CsvFormat, separator, |

        IniRead, t, %ini%, CsvFormat, timestamp, Timestamp

        IniRead, d, %ini%, CsvFormat, desc, Description

        IniRead, g, %ini%, CsvFormat, tags, Tag(s)

        Gui, 2:Default

        Gui, 2:+ToolWindow +LabelViewer

        Gui, Add, ListView, w350 r7 gSet, %t%|%d%|%g%

        Parse:

        LV_Delete()

        Loop, Read, %f%

        	Loop, Parse, A_LoopReadLine, %s%

        		If A_Index = 3

        			LV_Add("", v1, v2, A_LoopField)

        		Else v%A_Index% = %A_LoopField%

        LV_Delete(1)

        Loop, 3

        	LV_ModifyCol(A_Index, "AutoHdr")

        Gui, Show, , LifeLogger Viewer

        Return

        ViewerEscape:

        ViewerClose:

        ExitApp

        

        Set:

        If A_GuiEvent != DoubleClick

        	Return

        LV_GetText(v2, A_EventInfo, 2)

        Gui, +OwnDialogs

        InputBox, v, %d%, Enter a new description:, , , 125, , , , , %v2%

        If ErrorLevel

        	Return

        LV_GetText(v1, A_EventInfo)

        FileRead, x, %f%

        StringReplace, x, x, `n%v1%|%v2%|, `n%v1%|%v%|

        FileDelete, %f%

        FileAppend, %x%, %f%

        x = 

        Goto, Parse[/color]

      ]]>

      </challenge:code>

    </challenge:instance>

  </soap:Body>

</soap:Envelope>


Ace_NoOne
  • Members
  • 299 posts
  • Last active: May 02 2008 08:19 AM
  • Joined: 10 Oct 2005
Haha, very clever response there!
Now let your Bangalore coding slaves go to bed - this is simply inhumane! :shock:

Of course I'll incorporate this code into the next version of LifeLogger. :)

gamadren
  • Members
  • 8 posts
  • Last active: Feb 23 2010 01:28 AM
  • Joined: 28 Nov 2006
I really like this script. I use it daily and I don't have the skill-set to implement changes, but I would like to do some data mining. Maybe have a menu option to filter entries by tag and display the results.

Hopefully this can make it into the next version of LifeLogger!

Ace_NoOne
  • Members
  • 299 posts
  • Last active: May 02 2008 08:19 AM
  • Joined: 10 Oct 2005

I really like this script. I use it daily

Really? Glad to hear that!

I don't have the skill-set to implement changes

Neither do I! :lol: (It's true, ask around here... )
If you don't mind my asking though, how/where did you hear about this script then? After all, these are the AutoHotkey forums, meaning AHK coders hang around here, and I haven't published the script anywhere else.

I would like to do some data mining. Maybe have a menu option to filter entries by tag and display the results.
Hopefully this can make it into the next version of LifeLogger!

According to the original concept, this script is just for adding new entries. For further processing, you should use a spreadsheet app (MS Excel or OOo Calc); the autofilter should do the trick for you there. (If you don't know how to use that, send me a private message and I'll help you out.)
That's why the output is CSV-like instead of XML (listen up, Titan).

As for further development ... well, I'd really love to include some kind of auto-suggestion for tags (based on a list of previously used tags), but that might quickly become very complicated (i.e. too complex for me - see above).
Other than that, I currently don't have any ideas that could be easily implemented (unfortunately, I don't have a lot of time and/or patience these days).

gamadren
  • Members
  • 8 posts
  • Last active: Feb 23 2010 01:28 AM
  • Joined: 28 Nov 2006

If you don't mind my asking though, how/where did you hear about this script then? After all, these are the AutoHotkey forums, meaning AHK coders hang around here, and I haven't published the script anywhere else.


Lifehacker.com post on mouser (keyboard control of mouse) -> installed autohotkey -> checked the forums for other cool stuff ->Found yours and others->currently learning how to modify scripts.

Ace_NoOne
  • Members
  • 299 posts
  • Last active: May 02 2008 08:19 AM
  • Joined: 10 Oct 2005
If AHK were for profit, Chris would have to pay Lifehacker for all their promotions... ;)
I'm a regular LH reader as well by the way.

How'd it go with the analysis in Excel/Calc?
I've actually started work on a built-in module for very simple analysis of the logs, called xSV Editor for now. It's far from being finished, but you might still be interested...

gamadren
  • Members
  • 8 posts
  • Last active: Feb 23 2010 01:28 AM
  • Joined: 28 Nov 2006
Well, I didn't try spreadsheet analysis, I decided to try to make the change myself. :) And I believe I was successful.

I added a File menu option to "filter active log" which pops open an input box. Using that input it then searches the log using a regexp search to limit the search to only tags. The results are saved to 'filterresults.txt' and displayed.

I have tried your *SV Editor, and it is very nice. It will be much nicer than my solution when integrated with LifeLogger, but I figured I would post the LifeLogger code with my changes.

I am not sure of protocol when changing someone else's code, so I only put in my changes and didn't alter things like version numbers, changelog, etc. I hope this is okay, and if it isn't i will fix it.


/*
LifeLogger v0.8
 by FND

Simple interface to quickly create short entries in a CSV-like log file.

Inspired by QuickLoggerPlus by Kirk Friggstad, which is based on QuickLogger
by Gina Trapani, which in turn is based on (VBS) code by Joshua Fitzgerald
*/

/*
ToDo:
- add options menu
- add selection list for (recently/frequently used) tags
- add option to auto-rotate filenames (new file each day/week/month/year)
- integrate simple CSV editor (external module => pass column separator?)
*/

/*
Changelog
¯¯¯¯¯¯¯¯¯
# v0.8 (2006-11-06)
* first version based on QuickLogger++ (unreleased adaptation of QuickLoggerPlus)
* added tagging functionality to the original concept
*/

/*
********** settings, variable declarations **********
*/

#SingleInstance Force
OnExit, quit

programName = LifeLogger
programVersion = 0.8
programFullName = %programName% v%programVersion%
programAuthor = FND

configFile = LifeLogger.ini
filterResultsFile = filterresults.txt
/*
********** auto-execute section **********
*/

; construct tray menu
GoSub, trayMenu
; getSettings
GoSub, getSettings
; get current time
GoSub, getTime
; construct GUI
GoSub, showGUI
; end of auto-execute section
Return

/*
********** hotkeys **********
*/

; [ESC]: terminate script
Esc::
   Suspend ; exempt from suspension
   GoSub, quit
Return

/*
********** subroutines **********
*/

; construct GUI
showGUI:
   ; menu bar
   Menu, fileMenu, Add, Select active &log, logFileSelect
   Menu, fileMenu, Add, Show &active log, logFileOpen
   Menu, fileMenu, Add, &Filter active log, logFileFilter
   Menu, fileMenu, Add
   Menu, fileMenu, Add, E&xit, quit
   Menu, HelpMenu, Add, &About, about
   Menu, menuBar, Add, &File, :fileMenu
   Menu, menuBar, Add, &?, :HelpMenu
   Gui, Menu, menuBar
   ; GUI items
   Gui, Font, Bold
   Gui, Add, Text, x6 y7 w100, %timestampHeading%
   Gui, Font, Norm
   Gui, Add, Edit, x6 y27 w100 vTimestamp, %now%
   Gui, Font, Bold
   Gui, Add, Text, x116 y7 w300, %descHeading%
   Gui, Font, Norm
   Gui, Add, Edit, x116 y27 w300 vDesc,
   Gui, Font, Bold
   Gui, Add, Text, x426 y7 w150, %tagsHeading%
   Gui, Font, Norm
   Gui, Add, Edit, x426 y27 w150 vTags,
   Gui, Add, Button, x366 y67 w100, Cancel ; DEBUG - to do: same as ESC key
   Gui, Add, Button, x476 y67 w100 default, OK
   Gui, Show ,, %programName%
   ; skip timestamp field
   If (skipTimestamp = True)
   {
      Send, {Tab} ; DEBUG: dirty hack!?
   }
Return

ButtonOK:
   ; save inputs
   Gui, Submit
   ; trim leading and trailing spaces
   timestamp = %timestamp%
   desc = %desc%
   tags = %tags%
   ; write to log file
   GoSub, writeLog
   ; terminate script
   GoSub, quit
Return

logFileSelect:
   FileSelectFile, logFile, 2, %A_WorkingDir%
      , Please specify the name of the file to write log entries to.
Return

logFileOpen:
    IfExist, %logFile%
        Run, %logFile%
   Else
        MsgBox, Log file does not exist.
Return
logFileFilter:
		
	IfNotExist, %logFile%
        MsgBox, Log file does not exist.
    Else
        InputBox, UserInputFilter, Filter by Tag, Please enter a tag to filter by., , 400, 120
		if ErrorLevel
			return
		else
		expr = i).*\|.*\|.*%UserInputFilter%	;Looks for "anything'|'anything'|'tag" and is case insensitive
		
		;Comment the next line to append to rather than overwrite the existing file.
		FileDelete, %filterResultsFile%
		Loop, read, %logFile%, %filterResultsFile%
			{
				If RegExMatch( A_LoopReadLine, expr) >0
					FileAppend, %A_LoopReadLine%`n
			}
			
		IfExist, %filterResultsFile%
			Run, %filterResultsFile%	
		Else
			MsgBox, No tags match your input "%UserInputFilter%"
Return

ButtonCancel:
GuiClose:
   GoSub, quit
Return

; write to log file
writeLog:
   ; check for invalid chars
   checkValidity(timestamp, "Timestamp")
   checkValidity(desc, "Description")
   checkValidity(tags, "Tag")
   ; create log file with column headings if it doesn't exist already
   IfNotExist, %logFile%
   FileAppend
         , % timestampHeading . separator . descHeading . separator . tagsHeading . "`n"
         , %lfModifier%%logFile%
   ; write to file
   FileAppend
      , % timestamp . separator . desc . separator . tags . "`n"
      , %lfModifier%%logFile%
Return

; get current time
getTime:
   If (useUTC = True)
   {
       FormatTime, now, %A_NowUTC%, %timeFormat%
   }
   Else
   {
       FormatTime, now, %A_Now%, %timeFormat%
   }
Return

; read user settings
getSettings:
   ; create config file if it does not exist yet
   IfNotExist, %configFile%
       GoSub, writeSettings
   ; read settings from file
   IniRead, logFileBase, %configFile%, logFile, logFileBase
    IniRead, logFileExt, %configFile%, logFile, logFileExt
    IniRead, skipTimestamp, %configFile%, interface, skipTimestamp
    IniRead, unixMode, %configFile%, CsvFormat, unixMode
    IniRead, useUTC, %configFile%, CsvFormat, useUTC
   IniRead, timeFormat, %configFile%, CsvFormat, timeFormat
   IniRead, separator, %configFile%, CsvFormat, separator ; DEBUG: filter potentially problematic chars (e.g. "`")!?
   IniRead, timestampHeading, %configFile%, CsvFormat, timestamp
   IniRead, descHeading, %configFile%, CsvFormat, desc
   IniRead, tagsHeading, %configFile%, CsvFormat, tags
   ; convert True/False strings to actual boolean values
   stringToBoolean(skipTimestamp)
   stringToBoolean(unixMode)
   stringToBoolean(useUTC)
   ; process settings
    logFile = %logFileBase%.%logFileExt%
    If (unixMode = True)
      lfModifier = * ; use Unix mode for linefeeds (LF)
   Else
       lfModifier = ; use Windows mode for linefeeds (CR+LF)
Return

; write user settings - DEBUG: to do (currently just for initialization)
writeSettings:
   IniWrite, LifeLogger, %configFile%, logFile, logFileBase
    IniWrite, log, %configFile%, logFile, logFileExt
   IniWrite, True, %configFile%, interface, skipTimestamp
    IniWrite, True, %configFile%, CsvFormat, unixMode
    IniWrite, True, %configFile%, CsvFormat, useUTC
   IniWrite, yyyy-MM-dd hh:mm, %configFile%, CsvFormat, timeFormat
   IniWrite, |, %configFile%, CsvFormat, separator
   ; log file format
   IniWrite, Timestamp, %configFile%, CsvFormat, timestamp
   IniWrite, Description, %configFile%, CsvFormat, desc
   IniWrite, Tag(s), %configFile%, CsvFormat, tags
Return

; check for invalid chars
checkValidity(ByRef var, varTitle)
{
   Global separator
   Global programName
   If var Contains %separator%
   {
      MsgBox, 0, %programName%,
         ( LTrim
            Error: %varTitle% contains column separator.
            Respective characters will be automatically removed.
         )
      cleanse(var, "")
   }
}

; remove potentially problematic chars
cleanse(ByRef string, cleanChar)
{
   ; remove column separators
   Global separator
    StringReplace, string, string, %separator%, %cleanChar%, All
}

; convert True/False strings to actual boolean values
stringToBoolean(ByRef var)
{
   If var = True
       var := True
   Else
       var := False
}

; construct tray menu
trayMenu:
   ; set tray tip
   Menu, Tray, Tip, %programFullName%
   ; disable standard menu items
   Menu, Tray, NoStandard
   ; show info message
   Menu, Tray, Add, &About, about
   ; separator
   Menu, Tray, Add
   ; terminate script
   Menu, Tray, Add, E&xit, quit
Return

; show info message - DEBUG: to do
about:
   MsgBox, 64, %programFullName%,
   ( LTrim Join
      %programFullName%`n
      %A_Space%by %programAuthor%`n
      `n
      Simple interface to quickly create short entries in a CSV-like log file.
      `n`n
      Inspired by QuickLoggerPlus by Kirk Friggstad, which is based on QuickLo
      gger`n
      by Gina Trapani, which in turn is based on (VBS) code by Joshua Fitzgera
      ld`n
      `n
      Use [ESC] to terminate the program.
   )
Return

; terminate script
quit:
   ; terminate script
   ExitApp
Return


Ace_NoOne
  • Members
  • 299 posts
  • Last active: May 02 2008 08:19 AM
  • Joined: 10 Oct 2005
At long last, I have made some changes to the code again, updating the version number to 0.85.

There are a few minor fixes, but I have also (slightly) re-arranged the settings in the INI file. That means that you should probably delete your old INI to have the program/script create a new one from scratch.
However, since I also changed the default linefeed mode from Unix to Windows, you might have to convert your log file's linefeeds accordingly (or edit the INI to restore Unix mode).
(See changelog in the code for the full list.)

What's missing now is mainly a ComboBox with a selection of previously used tags. I already have an (imperfect) concept for that, but it'll probably be a while before I get to implement it.
Other than that, the ToDo list in the code has quite a few other items, though those are mostly post-v1.0 I guess...

Well, I didn't try spreadsheet analysis, I decided to try to make the change myself. :) And I believe I was successful.

Yup, looks good.
The problem with this text-based approach though is that you have to parse each line in your head to find the column separators.
Speaking of which: Your subroutine expects the column separator to always be the pipe character ("|"), which means it will break if the user chose a different character for that...

I have tried your *SV Editor, and it is very nice. It will be much nicer than my solution when integrated with LifeLogger, but I figured I would post the LifeLogger code with my changes.

... if I (or anyone else) ever finish it...

I am not sure of protocol when changing someone else's code

You're very welcome to improve on the code or present alternatives!
I don't think there's any established protocol for changing the version number in such cases; that'd have to be decided on a by-case basis.