diff --git a/Kaju Admin App/Kaju Admin.xojo_project b/Kaju Admin App/Kaju Admin.xojo_project index e1b514e..daed2b5 100644 --- a/Kaju Admin App/Kaju Admin.xojo_project +++ b/Kaju Admin App/Kaju Admin.xojo_project @@ -8,6 +8,7 @@ FileTypeSet=FileTypes1;FileTypes1.xojo_filetypeset;&h352FB9F5;&h0;false Window=WndAdmin;WndAdmin.xojo_window;&h5D541828;&h0;false BuildSteps=Build Automation;Build Automation.xojo_code;&h378B80A5;&h0;false Module=Kaju;../Kaju Classes/Kaju.xojo_code;&h11400316;&h2570CF64;false +Module=KajuLocale;../Kaju Classes/KajuLocale.xojo_code;&h20D2554;&h2570CF64;false Window=KajuUpdateWindow;../Kaju Classes/KajuUpdateWindow.xojo_window;&h18AE3D9;&h2570CF64;false Class=UpdateChecker;../Kaju Classes/Kaju/UpdateChecker.xojo_code;&h70CF0A50;&h11400316;false Class=KajuException;../Kaju Classes/Kaju/KajuException.xojo_code;&h3047231F;&h11400316;false @@ -25,13 +26,13 @@ Class=FolderItemAlias;Other Classes/FolderItemAlias.xojo_code;&h53EF1AE5;&h6AF5D Class=HTTPSSocket;../Kaju Classes/Kaju/HTTPSSocket.xojo_code;&h5ACDFAEB;&h11400316;false AppMenuBar=MainMenuBar MajorVersion=1 -MinorVersion=0 +MinorVersion=1 SubVersion=0 NonRelease=0 Release=3 InfoVersion=Kaju Admin -LongVersion=v.1.0 -ShortVersion=1.0 +LongVersion=v.1.1 +ShortVersion=1.1 WinCompanyName=MacTechnologies Consulting WinInternalName= WinProductName= diff --git a/Kaju Admin App/Kaju Admin_DE.xojo_locale b/Kaju Admin App/Kaju Admin_DE.xojo_locale new file mode 100644 index 0000000..b1d600a Binary files /dev/null and b/Kaju Admin App/Kaju Admin_DE.xojo_locale differ diff --git a/Kaju Classes/Kaju/BinaryInformation.xojo_code b/Kaju Classes/Kaju/BinaryInformation.xojo_code index 5bf3698..b6e99fe 100644 --- a/Kaju Classes/Kaju/BinaryInformation.xojo_code +++ b/Kaju Classes/Kaju/BinaryInformation.xojo_code @@ -6,17 +6,17 @@ Inherits Kaju.Information dim r as boolean if not r and Hash.Trim = "" then - reason = "Missing Hash" + reason = KajuLocale.kMissingReason + " Hash" r = true end if if not r and URL.Trim = "" then - reason = "Missing URL" + reason = KajuLocale.kMissingReason + " URL" r = true end if if not r and IsExecutableNameRequired and ExecutableName.Trim = "" then - reason = "Missing Executable Name" + reason = KajuLocale.kMissingReason + " Executable Name" r = true end if @@ -121,6 +121,11 @@ Inherits Kaju.Information InitialValue="-2147483648" Type="Integer" #tag EndViewProperty + #tag ViewProperty + Name="IsValid" + Group="Behavior" + Type="Boolean" + #tag EndViewProperty #tag ViewProperty Name="Left" Visible=true diff --git a/Kaju Classes/Kaju/KajuException.xojo_code b/Kaju Classes/Kaju/KajuException.xojo_code index f73665b..a9571fb 100644 --- a/Kaju Classes/Kaju/KajuException.xojo_code +++ b/Kaju Classes/Kaju/KajuException.xojo_code @@ -10,13 +10,16 @@ Inherits RuntimeException #tag EndMethod - #tag Constant, Name = kErrorCantFindLibsFolder, Type = String, Dynamic = False, Default = \"Can\xE2\x80\x99t locate this applications Libs folder.", Scope = Public + #tag Constant, Name = kErrorCantFindLibsFolder, Type = String, Dynamic = True, Default = \"Can\xE2\x80\x99t locate this applications Libs folder.", Scope = Public + #Tag Instance, Platform = Any, Language = de, Definition = \"Kann den Applications Libs Ordner dieser Anwendung nicht finden." #tag EndConstant - #tag Constant, Name = kErrorImproperFunction, Type = String, Dynamic = False, Default = \"This function cannot be used on this platform.", Scope = Public + #tag Constant, Name = kErrorImproperFunction, Type = String, Dynamic = True, Default = \"This function cannot be used on this platform.", Scope = Public + #Tag Instance, Platform = Any, Language = de, Definition = \"Diese Funktion kann auf dieser Platform nicht benutzt werden." #tag EndConstant - #tag Constant, Name = kErrorMissingUpdateURL, Type = String, Dynamic = False, Default = \"The update URL is missing.", Scope = Public + #tag Constant, Name = kErrorMissingUpdateURL, Type = String, Dynamic = True, Default = \"The update URL is missing.", Scope = Public + #Tag Instance, Platform = Any, Language = de, Definition = \"Die Update URL fehlt." #tag EndConstant diff --git a/Kaju Classes/Kaju/UpdateChecker.xojo_code b/Kaju Classes/Kaju/UpdateChecker.xojo_code index 84407af..949c57e 100644 --- a/Kaju Classes/Kaju/UpdateChecker.xojo_code +++ b/Kaju Classes/Kaju/UpdateChecker.xojo_code @@ -97,7 +97,7 @@ Protected Class UpdateChecker exit do elseif raw = "" then - if HandleError( kErrorNoUpdateData ) then + if HandleError( KajuLocale.kErrorNoUpdateData ) then continue do else exit do @@ -106,14 +106,14 @@ Protected Class UpdateChecker raw = raw.DefineEncoding( Encodings.UTF8 ) - dim firstLine as string + dim firstLine as string dim remainder as string SeparatePacket( raw, firstLine, remainder ) raw = remainder dim sig as string = firstLine.Left( kUpdatePacketMarker.Len ) if StrComp( sig, kUpdatePacketMarker, 0 ) <> 0 then - if HandleError( kErrorIncorrectPacketMarker ) then + if HandleError( KajuLocale.kErrorIncorrectPacketMarker ) then continue do else exit do @@ -123,7 +123,7 @@ Protected Class UpdateChecker sig = firstLine.Mid( sig.Len + 1 ) sig = DecodeHex( sig ) if not Crypto.RSAVerifySignature( raw, sig, ServerPublicRSAKey ) then - if HandleError( kErrorIncorrectPacketSignature ) then + if HandleError( KajuLocale.kErrorIncorrectPacketSignature ) then continue do else exit do @@ -151,11 +151,11 @@ Protected Class UpdateChecker // dim dlg as new MessageDialog dlg.ActionButton.Visible = true - dlg.ActionButton.Caption = "Try Again" + dlg.ActionButton.Caption = KajuLocale.kTryAgainButton dlg.CancelButton.Visible = true - dlg.CancelButton.Caption = "Later" + dlg.CancelButton.Caption = KajuLocale.kLaterButton dlg.AlternateActionButton.Visible = false - dlg.Message = "An error has occurred. Would you like to try again now or later?" + dlg.Message = KajuLocale.kErrorOccurredMessage dlg.Explanation = msg dim btn as MessageDialogButton = dlg.ShowModal @@ -362,7 +362,7 @@ Protected Class UpdateChecker return true Exception err as RuntimeException - return not HandleError( kErrorBadUpdateData ) + return not HandleError( KajuLocale.kErrorBadUpdateData ) End Function #tag EndMethod @@ -417,7 +417,7 @@ Protected Class UpdateChecker #tag Method, Flags = &h21 Private Sub SeparatePacket(raw As String, ByRef firstLine As String, ByRef remainder As String) - // Separate the incoming packet by the EOL when we don't know exactly what + // Separate the incoming packet by the EOL when we don't know exactly what // the EOL is. dim rx as new RegEx @@ -570,18 +570,6 @@ Protected Class UpdateChecker #tag Constant, Name = kAllowUpdateWindow, Type = Double, Dynamic = False, Default = \"&b10000000", Scope = Public #tag EndConstant - #tag Constant, Name = kErrorBadUpdateData, Type = String, Dynamic = False, Default = \"The update data cannot be read.", Scope = Private - #tag EndConstant - - #tag Constant, Name = kErrorIncorrectPacketMarker, Type = String, Dynamic = False, Default = \"The update packet signature marker was incorrect.", Scope = Private - #tag EndConstant - - #tag Constant, Name = kErrorIncorrectPacketSignature, Type = String, Dynamic = False, Default = \"The RSA signature of the update packet cannot be verified.", Scope = Private - #tag EndConstant - - #tag Constant, Name = kErrorNoUpdateData, Type = String, Dynamic = False, Default = \"No update data was available.", Scope = Private - #tag EndConstant - #tag Constant, Name = kPreferencesName, Type = String, Dynamic = False, Default = \"Kaju_Preferences", Scope = Private #tag EndConstant diff --git a/Kaju Classes/Kaju/UpdateInformation.xojo_code b/Kaju Classes/Kaju/UpdateInformation.xojo_code index 1c3ea9d..2625a47 100644 --- a/Kaju Classes/Kaju/UpdateInformation.xojo_code +++ b/Kaju Classes/Kaju/UpdateInformation.xojo_code @@ -12,27 +12,27 @@ Inherits Kaju.Information dim r as boolean if not r and rxVersion.Search( Version ) is nil then - reason = "Version must be in one of these forms: 1, 1.2, 1.2.3, 1.2d4, 1.2a4, 1.2b4, 1.2.4b4, etc." + reason = KajuLocale.kVersionMustBeInFormReason + ": 1, 1.2, 1.2.3, 1.2d4, 1.2a4, 1.2b4, 1.2.4b4, etc." r = true end if if not r and AppName.Trim = "" then - reason = "Missing app name" + reason = KajuLocale.kMissingAppNameReason r = true end if if not r and MacBinary <> nil and not MacBinary.IsValid then - reason = "Mac Binary information is not valid: " + MacBinary.InvalidReason + reason = "Mac " + KajuLocale.kBinaryInfoInvalidReason + ": " + MacBinary.InvalidReason r = true end if if not r and WindowsBinary <> nil and not WindowsBinary.IsValid then - reason = "Windows Binary information is not valid: " + WindowsBinary.InvalidReason + reason = "Windows " + KajuLocale.kBinaryInfoInvalidReason + ": " + WindowsBinary.InvalidReason r = true end if if not r and LinuxBinary <> nil and not LinuxBinary.IsValid then - reason = "Linux Binary information is not valid: " + LinuxBinary.InvalidReason + reason = "Linux " + KajuLocale.kBinaryInfoInvalidReason + ": " + LinuxBinary.InvalidReason r = true end if diff --git a/Kaju Classes/KajuLocale.xojo_code b/Kaju Classes/KajuLocale.xojo_code new file mode 100644 index 0000000..1f35a31 --- /dev/null +++ b/Kaju Classes/KajuLocale.xojo_code @@ -0,0 +1,200 @@ +#tag Module +Protected Module KajuLocale + #tag Note, Name = About + + Any data that needs to be localized (strings, mostly) goes here. + + The only exceptions are strings that might need to be compared by the developer, + like error messages in KajuException. + #tag EndNote + + + #tag Constant, Name = kAppMarker, Type = String, Dynamic = False, Default = \"<>", Scope = Protected + #tag EndConstant + + #tag Constant, Name = kBadDownloadMessage, Type = String, Dynamic = True, Default = \"The downloaded file appears to be corrupted.", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Die heruntergeladene Datei scheint defekt zu sein." + #tag EndConstant + + #tag Constant, Name = kBinaryInfoInvalidReason, Type = String, Dynamic = True, Default = \"Binary information is not valid", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Bin\xC3\xA4re Informationen sind nicht valide" + #tag EndConstant + + #tag Constant, Name = kCancelButton, Type = String, Dynamic = True, Default = \"&Cancel", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"&Abbrechen" + #tag EndConstant + + #tag Constant, Name = kCannotSkipVersionsMessage, Type = String, Dynamic = True, Default = \"You cannot skip versions until you have updated to version <> or beyond.", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Sie k\xC3\xB6nnen keine Versionen \xC3\xBCberspringen bevor Sie nicht mindestens <> oder h\xC3\xB6her installiert haben." + #tag EndConstant + + #tag Constant, Name = kDownloadingMessage, Type = String, Dynamic = True, Default = \"Downloading...", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Herunterladen..." + #tag EndConstant + + #tag Constant, Name = kDryRunMessage, Type = String, Dynamic = True, Default = \"(Dry run\x2C not really installing)", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"(Testlauf\x2C keine wirkliche Installation)" + #tag EndConstant + + #tag Constant, Name = kErrorBadUpdateData, Type = String, Dynamic = True, Default = \"The update data cannot be read.", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Update Informationen k\xC3\xB6nnen nicht gelesen werden." + #tag EndConstant + + #tag Constant, Name = kErrorIncorrectPacketMarker, Type = String, Dynamic = True, Default = \"The update packet signature marker was incorrect.", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Die Update Paket Signatur war inkorrekt." + #tag EndConstant + + #tag Constant, Name = kErrorIncorrectPacketSignature, Type = String, Dynamic = True, Default = \"The RSA signature of the update packet cannot be verified.", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Die RSA Signatur des Update Paket kann nicht verifiziert werden." + #tag EndConstant + + #tag Constant, Name = kErrorNoUpdateData, Type = String, Dynamic = True, Default = \"No update data was available.", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Es standen keine Update Informationen zur Verf\xC3\xBCgung." + #tag EndConstant + + #tag Constant, Name = kErrorOccurredMessage, Type = String, Dynamic = True, Default = \"An error has occurred. Would you like to try again now or later\?", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Es ist ein Fehler aufgetreten. M\xC3\xB6chten Sie es jetzt oder sp\xC3\xA4ter noch einmal versuchen\?" + #tag EndConstant + + #tag Constant, Name = kGenericErrorMessage, Type = String, Dynamic = True, Default = \"An error has occurred.", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Es ist ein Fehler aufgetreten." + #tag EndConstant + + #tag Constant, Name = kInstallButton, Type = String, Dynamic = True, Default = \"Install Update", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Update installieren" + #tag EndConstant + + #tag Constant, Name = kLaterButton, Type = String, Dynamic = True, Default = \"Later", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Sp\xC3\xA4ter" + #tag EndConstant + + #tag Constant, Name = kMainNotice, Type = String, Dynamic = True, Default = \"A new version of <> is available!", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Eine neue <> Version ist verf\xC3\xBCgbar!" + #tag EndConstant + + #tag Constant, Name = kMissingAppNameReason, Type = String, Dynamic = True, Default = \"Missing app name", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"App Name fehlt" + #tag EndConstant + + #tag Constant, Name = kMissingReason, Type = String, Dynamic = False, Default = \"Missing", Scope = Protected + #tag EndConstant + + #tag Constant, Name = kNewVersionMarker, Type = String, Dynamic = False, Default = \"<>", Scope = Protected + #tag EndConstant + + #tag Constant, Name = kNoUpdateInfoMessage, Type = String, Dynamic = True, Default = \"NO UPDATE INFORMATION", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"KEINE UPDATE INFORMATIONEN" + #tag EndConstant + + #tag Constant, Name = kPaymentRequiredMessage, Type = String, Dynamic = True, Default = \"This update is not free and will require payment. Proceed anyway\?", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Das ist ein kostenpflichtiges Update. Dennoch installieren\?" + #tag EndConstant + + #tag Constant, Name = kProceedButton, Type = String, Dynamic = True, Default = \"Proceed", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Weiter" + #tag EndConstant + + #tag Constant, Name = kProcessingFileMessage, Type = String, Dynamic = True, Default = \"Processing file...", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Verarbeite Datei..." + #tag EndConstant + + #tag Constant, Name = kQuitButton, Type = String, Dynamic = True, Default = \"Quit && Install", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Beenden && Installieren" + #tag EndConstant + + #tag Constant, Name = kReadyMessage, Type = String, Dynamic = True, Default = \"Ready to install", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Zum Update bereit" + #tag EndConstant + + #tag Constant, Name = kReleaseNotesLabel, Type = String, Dynamic = True, Default = \"Release Notes:", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Informationen zur Ver\xC3\xB6ffentlichung:" + #tag EndConstant + + #tag Constant, Name = kRemindMeLaterButton, Type = String, Dynamic = True, Default = \"Remind Me Later", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Jetzt nicht" + #tag EndConstant + + #tag Constant, Name = kSecondaryNoticeMultiple, Type = String, Dynamic = True, Default = \"You have version <> and there are multiple updates available. Install one\?", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Sie haben Version <> und es stehen mehrere Updates zur Verf\xC3\xBCgung. Ein Update installieren\?" + #tag EndConstant + + #tag Constant, Name = kSecondaryNoticeOne, Type = String, Dynamic = True, Default = \"You have version <>. Would you like to install version <>\?", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Sie haben Version <>. M\xC3\xB6chten Sie die Version <> installieren\?" + #tag EndConstant + + #tag Constant, Name = kSkipVersionButton, Type = String, Dynamic = True, Default = \"Skip Version", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Version \xC3\xBCberspringen" + #tag EndConstant + + #tag Constant, Name = kStopButton, Type = String, Dynamic = True, Default = \"Stop", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Stopp" + #tag EndConstant + + #tag Constant, Name = kThisApplication, Type = String, Dynamic = True, Default = \"this application", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"diese Anwendung" + #tag EndConstant + + #tag Constant, Name = kThisVersionMarker, Type = String, Dynamic = False, Default = \"<>", Scope = Protected + #tag EndConstant + + #tag Constant, Name = kTryAgainButton, Type = String, Dynamic = True, Default = \"Try Again", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Erneut versuchen" + #tag EndConstant + + #tag Constant, Name = kTryLaterButton, Type = String, Dynamic = True, Default = \"Try Later", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Sp\xC3\xA4ter erneut versuchen" + #tag EndConstant + + #tag Constant, Name = kVersionMarker, Type = String, Dynamic = False, Default = \"<>", Scope = Protected + #tag EndConstant + + #tag Constant, Name = kVersionMustBeInFormReason, Type = String, Dynamic = True, Default = \"Version must be in one of these forms", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Version muss in einer der folgenden Formen eingegeben werden" + #tag EndConstant + + #tag Constant, Name = kVersionsLabel, Type = String, Dynamic = True, Default = \"Available Versions:", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Verf\xC3\xBCgbare Versionen:" + #tag EndConstant + + #tag Constant, Name = kWindowTitle, Type = String, Dynamic = True, Default = \"Update Available", Scope = Protected + #Tag Instance, Platform = Any, Language = de, Definition = \"Update verf\xC3\xBCgbar" + #tag EndConstant + + + #tag ViewBehavior + #tag ViewProperty + Name="Index" + Visible=true + Group="ID" + InitialValue="-2147483648" + Type="Integer" + #tag EndViewProperty + #tag ViewProperty + Name="Left" + Visible=true + Group="Position" + InitialValue="0" + Type="Integer" + #tag EndViewProperty + #tag ViewProperty + Name="Name" + Visible=true + Group="ID" + Type="String" + #tag EndViewProperty + #tag ViewProperty + Name="Super" + Visible=true + Group="ID" + Type="String" + #tag EndViewProperty + #tag ViewProperty + Name="Top" + Visible=true + Group="Position" + InitialValue="0" + Type="Integer" + #tag EndViewProperty + #tag EndViewBehavior +End Module +#tag EndModule diff --git a/Kaju Classes/KajuUpdateWindow.xojo_window b/Kaju Classes/KajuUpdateWindow.xojo_window index be1e092..b11a2ee 100644 --- a/Kaju Classes/KajuUpdateWindow.xojo_window +++ b/Kaju Classes/KajuUpdateWindow.xojo_window @@ -23,7 +23,7 @@ Begin Window KajuUpdateWindow MinWidth = 64 Placement = 2 Resizeable = False - Title = "#kWindowTitle" + Title = "#KajuLocale.kWindowTitle" Visible = True Width = 800 Begin HTMLViewer hvNotes @@ -52,7 +52,7 @@ Begin Window KajuUpdateWindow Bold = False ButtonStyle = "0" Cancel = False - Caption = "#kInstallButton" + Caption = "#KajuLocale.kInstallButton" Default = True Enabled = True Height = 20 @@ -83,7 +83,7 @@ Begin Window KajuUpdateWindow Bold = False ButtonStyle = "0" Cancel = True - Caption = "#kRemindMeLaterButton" + Caption = "#KajuLocale.kRemindMeLaterButton" Default = False Enabled = True Height = 20 @@ -114,7 +114,7 @@ Begin Window KajuUpdateWindow Bold = False ButtonStyle = "0" Cancel = False - Caption = "#kSkipVersionButton" + Caption = "#KajuLocale.kSkipVersionButton" Default = False Enabled = True Height = 20 @@ -230,7 +230,7 @@ Begin Window KajuUpdateWindow Selectable = False TabIndex = 7 TabPanelIndex = 0 - Text = "#kReleaseNotesLabel" + Text = "#KajuLocale.kReleaseNotesLabel" TextAlign = 0 TextColor = &c00000000 TextFont = "SmallSystem" @@ -264,7 +264,7 @@ Begin Window KajuUpdateWindow Selectable = False TabIndex = 8 TabPanelIndex = 0 - Text = "Downloading..." + Text = "#KajuLocale.kDownloadingMessage" TextAlign = 0 TextColor = &c00000000 TextFont = "System" @@ -302,6 +302,7 @@ Begin Window KajuUpdateWindow CertificatePassword= "" CertificateRejectionFile= ConnectionType = 2 + ForceSecure = False Height = 32 Index = -2147483648 InitialParent = "" @@ -372,7 +373,7 @@ Begin Window KajuUpdateWindow Selectable = False TabIndex = 10 TabPanelIndex = 0 - Text = "#kVersionsLabel" + Text = "#KajuLocale.kVersionsLabel" TextAlign = 0 TextColor = &c00000000 TextFont = "SmallSystem" @@ -410,7 +411,7 @@ Begin Window KajuUpdateWindow TextFont = "System" TextSize = 0.0 TextUnit = 0 - Top = 84 + Top = 87 Underline = False Visible = True Width = 101 @@ -544,22 +545,6 @@ End reverse.SortWith( updates ) - // - // Set up the labels - // - - if Updates.Ubound = 0 then - lblMain.Text = kMainNoticeOne - lblSecondary.Text = kSecondaryNoticeOne - lblSecondary.Text = lblSecondary.Text.ReplaceAll( kNewVersionMarker, Updates( 0 ).Version ) - else - lblMain.Text = kMainNoticeMultiple - lblSecondary.Text = kSecondaryNoticeMultiple - end if - - lblMain.Text = lblMain.Text.ReplaceAll( kAppMarker, AppName ) - lblSecondary.Text = lblSecondary.Text.ReplaceAll( kThisVersionMarker, Kaju.AppVersionString ) - // // Set up the menu with the available updates. // It will set up the rest of the controls. @@ -593,6 +578,21 @@ End self.Loading = true + // + // Set up the main labels + // + AppName = update.AppName + if pumUpdates.ListCount = 1 then + lblSecondary.Text = KajuLocale.kSecondaryNoticeOne + lblSecondary.Text = lblSecondary.Text.ReplaceAll( KajuLocale.kNewVersionMarker, update.Version ) + else + lblSecondary.Text = KajuLocale.kSecondaryNoticeMultiple + end if + + lblMain.Text = KajuLocale.kMainNotice + lblMain.Text = lblMain.Text.ReplaceAll( KajuLocale.kAppMarker, AppName ) + lblSecondary.Text = lblSecondary.Text.ReplaceAll( KajuLocale.kThisVersionMarker, Kaju.AppVersionString ) + // // Get the background picture, if any // @@ -638,7 +638,7 @@ End // dim source as string = update.ReleaseNotes if source = "" then - source = "NO UPDATE INFORMATION" + source = "" + KajuLocale.kNoUpdateInfoMessage + "" end if static tempFile as FolderItem = GetTemporaryFolderItem @@ -668,7 +668,7 @@ End #tag Method, Flags = &h21 Private Sub ShowError(msg As String = "") if msg.Trim = "" then - msg = kGenericErrorMessage + msg = KajuLocale.kGenericErrorMessage end if lblInstallMessage.Visible = true @@ -676,7 +676,7 @@ End pbProgress.Visible = false btnOK.Enabled = false - btnCancel.Caption = kTryLaterButton + btnCancel.Caption = KajuLocale.kTryLaterButton btnSkipVersion.Visible = false CurrentStage = Stage.UpdateError @@ -706,7 +706,7 @@ End #tag Getter Get if mAppName = "" then - mAppName = kThisApplication + mAppName = KajuLocale.kThisApplication end if return mAppName @@ -783,85 +783,6 @@ End #tag EndProperty - #tag Constant, Name = kAppMarker, Type = String, Dynamic = False, Default = \"<>", Scope = Private - #tag EndConstant - - #tag Constant, Name = kBadDownloadMessage, Type = String, Dynamic = False, Default = \"The downloaded file appears to be corrupted.", Scope = Private - #tag EndConstant - - #tag Constant, Name = kCancelButton, Type = String, Dynamic = False, Default = \"&Cancel", Scope = Private - #tag EndConstant - - #tag Constant, Name = kDownloadingMessage, Type = String, Dynamic = False, Default = \"Downloading...", Scope = Private - #tag EndConstant - - #tag Constant, Name = kDryRunMessage, Type = String, Dynamic = False, Default = \"(Dry run\x2C not really installing)", Scope = Private - #tag EndConstant - - #tag Constant, Name = kGenericErrorMessage, Type = String, Dynamic = False, Default = \"An error has occurred.", Scope = Private - #tag EndConstant - - #tag Constant, Name = kInstallButton, Type = String, Dynamic = False, Default = \"Install Update", Scope = Private - #tag EndConstant - - #tag Constant, Name = kMainNoticeMultiple, Type = String, Dynamic = False, Default = \"New versions of <> are available!", Scope = Private - #tag EndConstant - - #tag Constant, Name = kMainNoticeOne, Type = String, Dynamic = False, Default = \"A new version of <> is available!", Scope = Private - #tag EndConstant - - #tag Constant, Name = kNewVersionMarker, Type = String, Dynamic = False, Default = \"<>", Scope = Private - #tag EndConstant - - #tag Constant, Name = kPaymentRequiredMessage, Type = String, Dynamic = False, Default = \"This update is not free and will require payment. Proceed anyway\?", Scope = Private - #tag EndConstant - - #tag Constant, Name = kProceedButton, Type = String, Dynamic = False, Default = \"Proceed", Scope = Private - #tag EndConstant - - #tag Constant, Name = kProcessingFileMessage, Type = String, Dynamic = False, Default = \"Processing file...", Scope = Private - #tag EndConstant - - #tag Constant, Name = kQuitButton, Type = String, Dynamic = False, Default = \"Quit && Install", Scope = Private - #tag EndConstant - - #tag Constant, Name = kReadyMessage, Type = String, Dynamic = False, Default = \"Ready to install", Scope = Private - #tag EndConstant - - #tag Constant, Name = kReleaseNotesLabel, Type = String, Dynamic = False, Default = \"Release Notes:", Scope = Private - #tag EndConstant - - #tag Constant, Name = kRemindMeLaterButton, Type = String, Dynamic = False, Default = \"Remind Me Later", Scope = Private - #tag EndConstant - - #tag Constant, Name = kSecondaryNoticeMultiple, Type = String, Dynamic = False, Default = \"You have version <> and there are multiple updates available. Install one\?", Scope = Private - #tag EndConstant - - #tag Constant, Name = kSecondaryNoticeOne, Type = String, Dynamic = False, Default = \"You have version <>. Would you like to install version <>\?", Scope = Private - #tag EndConstant - - #tag Constant, Name = kSkipVersionButton, Type = String, Dynamic = False, Default = \"Skip Version", Scope = Private - #tag EndConstant - - #tag Constant, Name = kStopButton, Type = String, Dynamic = False, Default = \"Stop", Scope = Private - #tag EndConstant - - #tag Constant, Name = kThisApplication, Type = String, Dynamic = False, Default = \"this application", Scope = Private - #tag EndConstant - - #tag Constant, Name = kThisVersionMarker, Type = String, Dynamic = False, Default = \"<>", Scope = Private - #tag EndConstant - - #tag Constant, Name = kTryLaterButton, Type = String, Dynamic = False, Default = \"Try Later", Scope = Private - #tag EndConstant - - #tag Constant, Name = kVersionsLabel, Type = String, Dynamic = False, Default = \"Available Versions:", Scope = Private - #tag EndConstant - - #tag Constant, Name = kWindowTitle, Type = String, Dynamic = False, Default = \"Update Available", Scope = Private - #tag EndConstant - - #tag Enum, Name = Stage, Type = Integer, Flags = &h21 ChoosingUpdate InstallingUpdate @@ -911,9 +832,9 @@ End if chosen.RequiresPayment then dim dlg as new MessageDialog dlg.ActionButton.Visible = true - dlg.ActionButton.Caption = kProceedButton + dlg.ActionButton.Caption = KajuLocale.kProceedButton dlg.CancelButton.Visible = true - dlg.Message = kPaymentRequiredMessage + dlg.Message = KajuLocale.kPaymentRequiredMessage dim btn as MessageDialogButton = dlg.ShowModalWithin( self ) if btn is dlg.CancelButton then @@ -925,7 +846,7 @@ End btnOK.Enabled = false - btnCancel.Caption = kStopButton + btnCancel.Caption = KajuLocale.kStopButton btnSkipVersion.Visible = false pbProgress.Visible = true @@ -937,11 +858,11 @@ End if Checker.DryRun then - lblInstallMessage.Text = kDryRunMessage + lblInstallMessage.Text = KajuLocale.kDryRunMessage else - lblInstallMessage.Text = kDownloadingMessage + lblInstallMessage.Text = KajuLocale.kDownloadingMessage dim tempFolder as FolderItem = Kaju.GetTemporaryFolder DeleteOnCancel.Append tempFolder @@ -1011,9 +932,10 @@ End dim info as Kaju.UpdateInformation = pumUpdates.RowTag( pumUpdates.ListIndex ) if info.MinimumRequiredVersion <> "" and _ - Kaju.VersionToDouble( Kaju.AppVersionString ) < Kaju.VersionToDouble( info.MinimumRequiredVersion ) then - - MsgBox "You cannot skip versions until you have updated to version " + info.MinimumRequiredVersion + " or beyond." + Kaju.VersionToDouble( Kaju.AppVersionString ) < Kaju.VersionToDouble( info.MinimumRequiredVersion ) then + dim msg as string = KajuLocale.kCannotSkipVersionsMessage + msg = msg.ReplaceAll( KajuLocale.kVersionMarker, info.MinimumRequiredVersion ) + MsgBox msg else @@ -1067,14 +989,14 @@ End elseif Kaju.HashOfFile( file ) <> SelectedUpdate.PlatformBinary.Hash then - ShowError( kBadDownloadMessage ) + ShowError( KajuLocale.kBadDownloadMessage ) else // // We have the file and it appears to be good // - lblInstallMessage.Text = kProcessingFileMessage + lblInstallMessage.Text = KajuLocale.kProcessingFileMessage dim targetFolder as FolderItem #if TargetWin32 then @@ -1150,14 +1072,14 @@ End Initiater.ReplacementExecutableName = SelectedUpdate.PlatformBinary.ExecutableName btnOK.Enabled = true - btnOK.Caption = kQuitButton + btnOK.Caption = KajuLocale.kQuitButton btnCancel.Visible = true - btnCancel.Caption = kCancelButton + btnCancel.Caption = KajuLocale.kCancelButton pbProgress.Visible = false lblInstallMessage.Visible = true - lblInstallMessage.Text = kReadyMessage + lblInstallMessage.Text = KajuLocale.kReadyMessage CurrentStage = Stage.WaitingToQuit diff --git a/Kaju Update Test v1.kaju b/Kaju Update Test v1.kaju index c7c4eda..6fb3836 100644 --- a/Kaju Update Test v1.kaju +++ b/Kaju Update Test v1.kaju @@ -11,39 +11,39 @@ "AppName":"Kaju Update Test", "RequiresPayment":true, "MacBinary":{ - "Hash":"B8BD64A5344FD70D6589F524ABAD4641", + "Hash":"114C37B75F89AE3615F127400CD31EA2", "URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Mac.zip" }, "WindowsBinary":{ - "Hash":"C48638358EA795D7667AF3E7EA91DCF8", + "Hash":"950C04FE1B3CFED190A338DCF4F926A3", "URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Win.zip", "ExecutableName":"Kaju Update Test.exe" }, "LinuxBinary":{ - "Hash":"B142E03F2AA5048DE5D9ECAB85ED4A96", + "Hash":"94B65B5F78351C295E61B4764FCE7B3A", "URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Linux.zip", "ExecutableName":"Kaju Update Test" } }, { "Version":"1.2.2d5", - "ReleaseNotes":"

A phony development version pointing to the same binary. Meant as a placeholder to demonstrate multiple versions.<\/p>", + "ReleaseNotes":"

A phony development version pointing to the same binary. Meant as a placeholder to demonstrate multiple versions.<\/p>\n\n

Note that this version has a name change.<\/p>", "ImageURL":"", "UseTransparency":false, "MinimumRequiriedVersion":"", - "AppName":"Kaju Update Test", + "AppName":"New Kaju Update Test", "RequiresPayment":false, "MacBinary":{ - "Hash":"B8BD64A5344FD70D6589F524ABAD4641", + "Hash":"114C37B75F89AE3615F127400CD31EA2", "URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Mac.zip" }, "WindowsBinary":{ - "Hash":"C48638358EA795D7667AF3E7EA91DCF8", + "Hash":"950C04FE1B3CFED190A338DCF4F926A3", "URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Win.zip", "ExecutableName":"Kaju Update Test.exe" }, "LinuxBinary":{ - "Hash":"B142E03F2AA5048DE5D9ECAB85ED4A96", + "Hash":"94B65B5F78351C295E61B4764FCE7B3A", "URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Linux.zip", "ExecutableName":"Kaju Update Test" } @@ -57,16 +57,16 @@ "AppName":"Kaju Update Test", "RequiresPayment":false, "MacBinary":{ - "Hash":"B8BD64A5344FD70D6589F524ABAD4641", + "Hash":"114C37B75F89AE3615F127400CD31EA2", "URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Mac.zip" }, "WindowsBinary":{ - "Hash":"C48638358EA795D7667AF3E7EA91DCF8", + "Hash":"950C04FE1B3CFED190A338DCF4F926A3", "URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Win.zip", "ExecutableName":"Kaju Update Test.exe" }, "LinuxBinary":{ - "Hash":"B142E03F2AA5048DE5D9ECAB85ED4A96", + "Hash":"94B65B5F78351C295E61B4764FCE7B3A", "URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Linux.zip", "ExecutableName":"Kaju Update Test" } @@ -103,16 +103,16 @@ "AppName":"Kaju Update Test", "RequiresPayment":false, "MacBinary":{ - "Hash":"B8BD64A5344FD70D6589F524ABAD4641", + "Hash":"114C37B75F89AE3615F127400CD31EA2", "URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Mac.zip" }, "WindowsBinary":{ - "Hash":"C48638358EA795D7667AF3E7EA91DCF8", + "Hash":"950C04FE1B3CFED190A338DCF4F926A3", "URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Win.zip", "ExecutableName":"Kaju Update Test.exe" }, "LinuxBinary":{ - "Hash":"B142E03F2AA5048DE5D9ECAB85ED4A96", + "Hash":"94B65B5F78351C295E61B4764FCE7B3A", "URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Linux.zip", "ExecutableName":"Kaju Update Test" } diff --git a/README.md b/README.md index 402957a..6a0b766 100644 --- a/README.md +++ b/README.md @@ -275,6 +275,10 @@ This project was designed and implemented by: With thanks to John Hansen and Paul Lefebvre. +Translations to other languages by: + +* Sascha Schneppmueller (German) + With special thanks to [Advanced Medical Pricing Solutions, Inc.](http://www.advancedpricing.com), for making this possible. ## FAQ @@ -297,6 +301,19 @@ No. No. Thanks to John Hansen and code he provided on the [Xojo Forums](https://forum.xojo.com), Windows will even unzip the downloaded file without any extra help. +**How do I contribute?** + +For the appropriate branch to your GitHub account. Use "develop" for general fixes and additions and "translations" to add a language translation. Make your changes, then submit a pull request. We'll look it over and merge what's appropriate or provide feedback. + +**I want to submit a translation. What should be translated?** + +There are two places to look for strings that need translation: + +1. The constants in the KajuLocale module. +1. The error messages in KajuException. + +Add a translation for each, then submit a pull request as outlined above. + ## Release Notes 1.0 (Jan. 5, 2015) @@ -307,3 +324,10 @@ No. Thanks to John Hansen and code he provided on the [Xojo Forums](https://foru - Fixed redirect bug. - The URL will set Secure and the Port (can override in the URL itself). + +1.1 (Jan. 11, 2015) + +- Moved user-presented strings to KajuLocale module for easier translation. +- Fixed bug where the app name was not being presented in the Update window. +- Changed behavior of how the "A never version of..." message is presented in the Update window. +- German translation. diff --git a/Update Test App/Kaju Update Test.xojo_project b/Update Test App/Kaju Update Test.xojo_project index a1b195e..054e6bd 100644 --- a/Update Test App/Kaju Update Test.xojo_project +++ b/Update Test App/Kaju Update Test.xojo_project @@ -8,6 +8,7 @@ Picture=Some_Image;../External Images/Some_Image.png;&h1B5C6827;&h0;false;0;&h0 BuildSteps=Build Automation;Build Automation.xojo_code;&h17423755;&h0;false Folder=Kaju Classes;../Kaju Classes;&h2570CF64;&h0;false Module=Kaju;../Kaju Classes/Kaju.xojo_code;&h11400316;&h2570CF64;false +Module=KajuLocale;../Kaju Classes/KajuLocale.xojo_code;&h20D2554;&h2570CF64;false Class=UpdateChecker;../Kaju Classes/Kaju/UpdateChecker.xojo_code;&h70CF0A50;&h11400316;false Class=KajuException;../Kaju Classes/Kaju/KajuException.xojo_code;&h3047231F;&h11400316;false Class=UpdateInformation;../Kaju Classes/Kaju/UpdateInformation.xojo_code;&h79AE1ADC;&h11400316;false diff --git a/Update Test Files (Upload These)/Kaju_Update_Test_Linux.zip b/Update Test Files (Upload These)/Kaju_Update_Test_Linux.zip index bfb3fc9..5b1fea3 100644 Binary files a/Update Test Files (Upload These)/Kaju_Update_Test_Linux.zip and b/Update Test Files (Upload These)/Kaju_Update_Test_Linux.zip differ diff --git a/Update Test Files (Upload These)/Kaju_Update_Test_Mac.zip b/Update Test Files (Upload These)/Kaju_Update_Test_Mac.zip index d555be1..2a546e1 100644 Binary files a/Update Test Files (Upload These)/Kaju_Update_Test_Mac.zip and b/Update Test Files (Upload These)/Kaju_Update_Test_Mac.zip differ diff --git a/Update Test Files (Upload These)/Kaju_Update_Test_Win.zip b/Update Test Files (Upload These)/Kaju_Update_Test_Win.zip index fe15bd6..2a6d16a 100644 Binary files a/Update Test Files (Upload These)/Kaju_Update_Test_Win.zip and b/Update Test Files (Upload These)/Kaju_Update_Test_Win.zip differ diff --git a/Update Test Files (Upload These)/UpdateInformation.html b/Update Test Files (Upload These)/UpdateInformation.html index cf31d88..041122a 100644 --- a/Update Test Files (Upload These)/UpdateInformation.html +++ b/Update Test Files (Upload These)/UpdateInformation.html @@ -1,4 +1,4 @@ -KAJU 45F07892CD454DC66666A5B5397E05DCAADAC67324F4FA99E38A8030FC0F7DB3C376235F704B21B11A525126C958BD702A4BF8D353946B56AD42076D230573C0D30CF7D221EE69AC8E2D9B234CF4B6242316BDB367543BE71A97418D1C57090C20CFAAFED9846359E66827F3A75819784D599EDB6D1A38D3C70C05E6E8CC0AEE8994A124571FBE2727FC0B5659ECED50D091C547F8B0D649AAD76775A795945BC1D2A3F68BEEFAEA2F421B257F321C969EC046030FB5C34664884E02260E5A9D65DF923251CAB1738761EF2AB54E8E88FB3CE4E7873298E3481F646D5EF54D2D24FCD657931A9B70AE85E05789B5F06E791ADA23EAADCEF91CB1B37DC90D1D17 +KAJU 368102B4C09217104B60ADFEEC5AA315476E2A6F5D330784725E351C9C82D89C4220AD12F17CC1C8CE89B887D18CFAA0443959263586128D1C872EAB1C86B0468AB3F49859340D9E8F1B8A5CDBB35CE1B230522A46F7105B4D5236B40D4132A5EE8751004F9501D27D974A22584FDB3DCED7AB8C6F3E4BE968DFFA8179044BDD0E4DCFBC7E567150B8B435D4C695D8F8EF48E3DCFC898022F0F516B9B620F6EE0ED9F7F75A3528A9F7E4C930C0ED92A324F489A82C2DDBF11254C8410129310EBA89E1A60F5588C8F437635EDBF2F20CB8AAA4AB60F0F3151227519E70786807777EFD0A7BD9DA3E7ACC584CF63F528214C86C6FE04A4625713EDCC7D2F0783C [ { "Version":"1.1", @@ -9,39 +9,39 @@ "AppName":"Kaju Update Test", "RequiresPayment":true, "MacBinary":{ - "Hash":"B8BD64A5344FD70D6589F524ABAD4641", + "Hash":"114C37B75F89AE3615F127400CD31EA2", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Mac.zip" }, "WindowsBinary":{ - "Hash":"C48638358EA795D7667AF3E7EA91DCF8", + "Hash":"950C04FE1B3CFED190A338DCF4F926A3", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Win.zip", "ExecutableName":"Kaju Update Test.exe" }, "LinuxBinary":{ - "Hash":"B142E03F2AA5048DE5D9ECAB85ED4A96", + "Hash":"94B65B5F78351C295E61B4764FCE7B3A", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Linux.zip", "ExecutableName":"Kaju Update Test" } }, { "Version":"1.2.2d5", - "ReleaseNotes":"

A phony development version pointing to the same binary. Meant as a placeholder to demonstrate multiple versions.

", + "ReleaseNotes":"

A phony development version pointing to the same binary. Meant as a placeholder to demonstrate multiple versions.

\n\n

Note that this version has a name change.

", "ImageURL":"", "UseTransparency":false, "MinimumRequiriedVersion":"", - "AppName":"Kaju Update Test", + "AppName":"New Kaju Update Test", "RequiresPayment":false, "MacBinary":{ - "Hash":"B8BD64A5344FD70D6589F524ABAD4641", + "Hash":"114C37B75F89AE3615F127400CD31EA2", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Mac.zip" }, "WindowsBinary":{ - "Hash":"C48638358EA795D7667AF3E7EA91DCF8", + "Hash":"950C04FE1B3CFED190A338DCF4F926A3", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Win.zip", "ExecutableName":"Kaju Update Test.exe" }, "LinuxBinary":{ - "Hash":"B142E03F2AA5048DE5D9ECAB85ED4A96", + "Hash":"94B65B5F78351C295E61B4764FCE7B3A", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Linux.zip", "ExecutableName":"Kaju Update Test" } @@ -55,16 +55,16 @@ "AppName":"Kaju Update Test", "RequiresPayment":false, "MacBinary":{ - "Hash":"B8BD64A5344FD70D6589F524ABAD4641", + "Hash":"114C37B75F89AE3615F127400CD31EA2", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Mac.zip" }, "WindowsBinary":{ - "Hash":"C48638358EA795D7667AF3E7EA91DCF8", + "Hash":"950C04FE1B3CFED190A338DCF4F926A3", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Win.zip", "ExecutableName":"Kaju Update Test.exe" }, "LinuxBinary":{ - "Hash":"B142E03F2AA5048DE5D9ECAB85ED4A96", + "Hash":"94B65B5F78351C295E61B4764FCE7B3A", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Linux.zip", "ExecutableName":"Kaju Update Test" } @@ -101,16 +101,16 @@ "AppName":"Kaju Update Test", "RequiresPayment":false, "MacBinary":{ - "Hash":"B8BD64A5344FD70D6589F524ABAD4641", + "Hash":"114C37B75F89AE3615F127400CD31EA2", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Mac.zip" }, "WindowsBinary":{ - "Hash":"C48638358EA795D7667AF3E7EA91DCF8", + "Hash":"950C04FE1B3CFED190A338DCF4F926A3", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Win.zip", "ExecutableName":"Kaju Update Test.exe" }, "LinuxBinary":{ - "Hash":"B142E03F2AA5048DE5D9ECAB85ED4A96", + "Hash":"94B65B5F78351C295E61B4764FCE7B3A", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Linux.zip", "ExecutableName":"Kaju Update Test" }