diff --git a/.gitignore b/.gitignore
index 1c193dc..6c8b391 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,6 @@ Kaju Admin App/Builds - Kaju Admin.xojo_project
Kaju Admin CLI/kaju.debug
Kaju Admin CLI/Builds - Kaju Admin CLI.xojo_project
*.gz
+Update Test App/Builds - Kaju Update Test
+Kaju Admin App/Builds - Kaju Admin
+Kaju Admin CLI/Builds - Kaju Admin CLI
diff --git a/Admin Classes/KajuFile.xojo_code b/Admin Classes/KajuFile.xojo_code
index d3dcb63..b36edf8 100644
--- a/Admin Classes/KajuFile.xojo_code
+++ b/Admin Classes/KajuFile.xojo_code
@@ -27,7 +27,7 @@ Protected Class KajuFile
data.EscapeSlashes = false
//
- // Perform $VERSION$ substitutions
+ // Perform $VERSION$ substitutions and add security token
//
dim keys() as string = Kaju.UpdateInformation.BinaryNames
@@ -97,7 +97,7 @@ Protected Class KajuFile
#tag EndMethod
#tag Method, Flags = &h0
- Shared Function InsertVersion(originalURL As String, version As String) As String
+ Shared Function InsertVersion(originalURL As String, version As String) As String
return originalURL.ReplaceAllB( "$VERSION$", version )
End Function
#tag EndMethod
@@ -261,6 +261,7 @@ Protected Class KajuFile
Group="ID"
InitialValue="-2147483648"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Left"
@@ -268,18 +269,23 @@ Protected Class KajuFile
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Top"
@@ -287,6 +293,7 @@ Protected Class KajuFile
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag EndViewBehavior
End Class
diff --git a/Custom Plist/Info.plist b/Custom Plist/Info.plist
new file mode 100644
index 0000000..6a6654d
--- /dev/null
+++ b/Custom Plist/Info.plist
@@ -0,0 +1,11 @@
+
+
+
", Scope = Private
+ #tag EndConstant
#tag EndWindowCode
@@ -2193,14 +2334,24 @@ End
#tag Events fldReleaseNotes
#tag Event
Sub TextChange()
+ objReleaseNotesProcessor.ReleaseNotes = me.Text
tmrUpdateReleaseNotesPreview.Mode = Timer.ModeSingle
tmrUpdateReleaseNotesPreview.Reset
+
+ #if TargetWindows then
+ hvReleaseNotesPreview.LoadPage( kNoDataHTML, nil )
+
+ dim releaseNotes as string = ControlValue( fldReleaseNotes ).StringValue
+ hvReleaseNotesPreview.LoadPage releaseNotes, nil
+ me.SetFocus
+ #endif
+
End Sub
#tag EndEvent
#tag EndEvents
#tag Events hvReleaseNotesPreview
#tag Event
- Function NewWindow() As HTMLViewer
+ Function NewWindow() As Object
return hvNewWindow
End Function
#tag EndEvent
@@ -2211,18 +2362,37 @@ End
#pragma unused URL
End Function
#tag EndEvent
+ #tag Event
+ Sub DocumentComplete(url as String)
+ #pragma unused URL
+
+ self.Loading = false
+ End Sub
+ #tag EndEvent
+ #tag Event
+ Sub Error(errorNumber as Integer, errorMessage as String)
+ #pragma unused errorNumber
+ #pragma unused errorMessage
+
+ break
+ End Sub
+ #tag EndEvent
#tag EndEvents
#tag Events fldImageURL
#tag Event
Sub TextChange()
tmrUpdateImagePreview.Mode = Timer.ModeSingle
tmrUpdateImagePreview.Reset
+
+ #if TargetWindows then
+ hvImagePreview.LoadPage kNoDataHTML, nil
+ #endif
End Sub
#tag EndEvent
#tag EndEvents
#tag Events hvImagePreview
#tag Event
- Function NewWindow() As HTMLViewer
+ Function NewWindow() As Object
return hvNewWindow
End Function
#tag EndEvent
@@ -2233,6 +2403,21 @@ End
#pragma unused URL
End Function
#tag EndEvent
+ #tag Event
+ Sub DocumentComplete(url as String)
+ #pragma unused URL
+
+ self.Loading = false
+ End Sub
+ #tag EndEvent
+ #tag Event
+ Sub Error(errorNumber as Integer, errorMessage as String)
+ #pragma unused errorNumber
+ #pragma unused errorMessage
+
+ break
+ End Sub
+ #tag EndEvent
#tag EndEvents
#tag Events btnStyle
#tag Event
@@ -2274,13 +2459,20 @@ End
Sub Action()
self.Loading = true
- dim releaseNotes as string = ControlValue( fldReleaseNotes ).StringValue
- if not cbPre2Preview.Value then
- releaseNotes = Kaju.ProcessReleaseNotes( releaseNotes )
+ dim releaseNotes as string
+ if cbPre2Preview.Value then
+ releaseNotes = ControlValue( fldReleaseNotes ).StringValue
+ else
+ releaseNotes = objReleaseNotesProcessor.DisplayReleaseNotes
end if
- hvReleaseNotesPreview.LoadPage( releaseNotes, RelativeToFolderItem )
- self.Loading = false
+ dim saveControl as RectControl = self.Focus
+ hvReleaseNotesPreview.LoadPage( releaseNotes, nil )
+ self.Focus = saveControl
+ //
+ // The htmlViewer will set Loading to false
+ //
+
End Sub
#tag EndEvent
#tag EndEvents
@@ -2309,7 +2501,10 @@ End
hvImagePreview.LoadURL( fldImageURL.Text )
- self.Loading = false
+ //
+ // The htmlViewer will set Loading to false
+ //
+
End Sub
#tag EndEvent
#tag EndEvents
@@ -2383,42 +2578,61 @@ End
End Sub
#tag EndEvent
#tag EndEvents
+#tag Events objReleaseNotesProcessor
+ #tag Event
+ Sub ReleaseNotesReceived()
+ tmrUpdateReleaseNotesPreview.Mode = Timer.ModeSingle
+ tmrUpdateReleaseNotesPreview.Reset
+ End Sub
+ #tag EndEvent
+#tag EndEvents
+#tag Events tmrAdjustControls
+ #tag Event
+ Sub Action()
+ AdjustControls true
+
+ End Sub
+ #tag EndEvent
+#tag EndEvents
#tag ViewBehavior
#tag ViewProperty
- Name="BackColor"
+ Name="MinimumWidth"
Visible=true
- Group="Appearance"
- InitialValue="&hFFFFFF"
- Type="Color"
+ Group="Size"
+ InitialValue="64"
+ Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="Backdrop"
+ Name="MinimumHeight"
Visible=true
- Group="Appearance"
- Type="Picture"
- EditorType="Picture"
+ Group="Size"
+ InitialValue="64"
+ Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="CloseButton"
+ Name="MaximumWidth"
Visible=true
- Group="Appearance"
- InitialValue="True"
- Type="Boolean"
- EditorType="Boolean"
+ Group="Size"
+ InitialValue="32000"
+ Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="Composite"
+ Name="MaximumHeight"
Visible=true
- Group="Appearance"
- InitialValue="False"
- Type="Boolean"
+ Group="Size"
+ InitialValue="32000"
+ Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="Frame"
+ Name="Type"
Visible=true
- Group="Appearance"
+ Group="Frame"
InitialValue="0"
- Type="Integer"
+ Type="Types"
EditorType="Enum"
#tag EnumValues
"0 - Document"
@@ -2435,148 +2649,155 @@ End
#tag EndEnumValues
#tag EndViewProperty
#tag ViewProperty
- Name="FullScreen"
- Group="Appearance"
- InitialValue="False"
+ Name="HasCloseButton"
+ Visible=true
+ Group="Frame"
+ InitialValue="True"
Type="Boolean"
- EditorType="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="FullScreenButton"
+ Name="HasMaximizeButton"
Visible=true
- Group="Appearance"
- InitialValue="False"
+ Group="Frame"
+ InitialValue="True"
Type="Boolean"
- EditorType="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="HasBackColor"
+ Name="HasMinimizeButton"
Visible=true
- Group="Appearance"
+ Group="Frame"
+ InitialValue="True"
+ Type="Boolean"
+ EditorType=""
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="HasFullScreenButton"
+ Visible=true
+ Group="Frame"
InitialValue="False"
Type="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="Height"
+ Name="DefaultLocation"
Visible=true
- Group="Position"
- InitialValue="400"
- Type="Integer"
+ Group="Behavior"
+ InitialValue="0"
+ Type="Locations"
+ EditorType="Enum"
+ #tag EnumValues
+ "0 - Default"
+ "1 - Parent Window"
+ "2 - Main Screen"
+ "3 - Parent Window Screen"
+ "4 - Stagger"
+ #tag EndEnumValues
#tag EndViewProperty
#tag ViewProperty
- Name="ImplicitInstance"
+ Name="HasBackgroundColor"
Visible=true
- Group="Appearance"
- InitialValue="True"
+ Group="Background"
+ InitialValue="False"
Type="Boolean"
- EditorType="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="Interfaces"
+ Name="BackgroundColor"
Visible=true
- Group="ID"
- Type="String"
- EditorType="String"
+ Group="Background"
+ InitialValue="&hFFFFFF"
+ Type="Color"
+ EditorType="Color"
#tag EndViewProperty
#tag ViewProperty
- Name="LiveResize"
+ Name="Backdrop"
Visible=true
Group="Appearance"
- InitialValue="True"
- Type="Boolean"
- EditorType="Boolean"
+ InitialValue=""
+ Type="Picture"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="Loading"
- Group="Behavior"
+ Name="Composite"
+ Visible=true
+ Group="Appearance"
+ InitialValue="False"
Type="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="MacProcID"
- Visible=true
+ Name="FullScreen"
+ Visible=false
Group="Appearance"
- InitialValue="0"
- Type="Integer"
+ InitialValue="False"
+ Type="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="MaxHeight"
+ Name="Height"
Visible=true
Group="Position"
- InitialValue="32000"
+ InitialValue="400"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="MaximizeButton"
+ Name="ImplicitInstance"
Visible=true
Group="Appearance"
InitialValue="True"
Type="Boolean"
- EditorType="Boolean"
- #tag EndViewProperty
- #tag ViewProperty
- Name="MaxWidth"
- Visible=true
- Group="Position"
- InitialValue="32000"
- Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="MenuBar"
+ Name="Interfaces"
Visible=true
- Group="Appearance"
- Type="MenuBar"
- EditorType="MenuBar"
+ Group="ID"
+ InitialValue=""
+ Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="MenuBarVisible"
- Group="Appearance"
- InitialValue="True"
+ Name="Loading"
+ Visible=false
+ Group="Behavior"
+ InitialValue=""
Type="Boolean"
- EditorType="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="MinHeight"
+ Name="MacProcID"
Visible=true
- Group="Position"
- InitialValue="64"
+ Group="Appearance"
+ InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="MinimizeButton"
+ Name="MenuBar"
Visible=true
Group="Appearance"
- InitialValue="True"
- Type="Boolean"
- EditorType="Boolean"
+ InitialValue=""
+ Type="MenuBar"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="MinWidth"
- Visible=true
- Group="Position"
- InitialValue="64"
- Type="Integer"
+ Name="MenuBarVisible"
+ Visible=false
+ Group="Appearance"
+ InitialValue="True"
+ Type="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
- EditorType="String"
- #tag EndViewProperty
- #tag ViewProperty
- Name="Placement"
- Visible=true
- Group="Position"
- InitialValue="0"
- Type="Integer"
- EditorType="Enum"
- #tag EnumValues
- "0 - Default"
- "1 - Parent Window"
- "2 - Main Screen"
- "3 - Parent Window Screen"
- "4 - Stagger"
- #tag EndEnumValues
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Resizeable"
@@ -2584,14 +2805,15 @@ End
Group="Appearance"
InitialValue="True"
Type="Boolean"
- EditorType="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
- EditorType="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Title"
@@ -2599,6 +2821,7 @@ End
Group="Appearance"
InitialValue="Untitled"
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Visible"
@@ -2606,7 +2829,7 @@ End
Group="Appearance"
InitialValue="True"
Type="Boolean"
- EditorType="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Width"
@@ -2614,5 +2837,6 @@ End
Group="Position"
InitialValue="600"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag EndViewBehavior
diff --git a/Kaju Admin CLI/FileHandlerSubApplication.xojo_code b/Kaju Admin CLI/FileHandlerSubApplication.xojo_code
index d91b316..bba9add 100644
--- a/Kaju Admin CLI/FileHandlerSubApplication.xojo_code
+++ b/Kaju Admin CLI/FileHandlerSubApplication.xojo_code
@@ -27,13 +27,17 @@ Inherits SubApplication
#tag ViewBehavior
#tag ViewProperty
Name="AdditionalHelp"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
#tag ViewProperty
Name="Description"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
@@ -43,6 +47,7 @@ Inherits SubApplication
Group="ID"
InitialValue="-2147483648"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Left"
@@ -50,18 +55,23 @@ Inherits SubApplication
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Top"
@@ -69,10 +79,13 @@ Inherits SubApplication
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Usage"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
diff --git a/Kaju Admin CLI/Kaju Admin CLI.xojo_project b/Kaju Admin CLI/Kaju Admin CLI.xojo_project
index 31aa2b9..feda6b3 100644
--- a/Kaju Admin CLI/Kaju Admin CLI.xojo_project
+++ b/Kaju Admin CLI/Kaju Admin CLI.xojo_project
@@ -1,45 +1,48 @@
Type=Console
-RBProjectVersion=2017.011
+RBProjectVersion=2019.031
MinIDEVersion=20070100
-Class=App;App.xojo_code;&h31FD87FF;&h0;false
-Module=FormatCodePreferences;FormatCodePreferences.xojo_code;&h2977F6F1;&h0;false
-BuildSteps=Build Automation;Build Automation.xojo_code;&h28989FFF;&h0;false
-Folder=Kaju Classes;../Kaju Classes;&h2570CF64;&h0;false
-Class=KajuFile;../Admin Classes/KajuFile.xojo_code;&h1A7FF7FF;&h0;false
-Folder=Other Classes;../Other Classes;&hF6057FF;&h0;false
-Class=SubApplication;SubApplication.xojo_code;&h2E4257FF;&h0;false
-Class=FileHandlerSubApplication;FileHandlerSubApplication.xojo_code;&h6664E7FF;&h0;false
-Class=VersionHandlerSubApplication;VersionHandlerSubApplication.xojo_code;&h2332B7FF;&h0;false
-Folder=OptionParser;../Other Classes/OptionParser;&h797A37FF;&hF6057FF;false
-Module=Kaju;../Kaju Classes/Kaju.xojo_code;&h11400316;&h2570CF64;false
-Class=KajuException;../Kaju Classes/Kaju/KajuException.xojo_code;&h3047231F;&h11400316;false
-Class=UpdateInformation;../Kaju Classes/Kaju/UpdateInformation.xojo_code;&h79AE1ADC;&h11400316;false
-Class=BinaryInformation;../Kaju Classes/Kaju/BinaryInformation.xojo_code;&hE8D70B5;&h11400316;false
-Class=Information;../Kaju Classes/Kaju/Information.xojo_code;&h6497A7C4;&h11400316;false
-Module=KajuLocale;../Kaju Classes/KajuLocale.xojo_code;&h20D2554;&h2570CF64;false
-Folder=Sub Applications;Sub Applications;&h58EA2FFF;&h0;false
-Class=AddVersionApp;Sub Applications/AddVersionApp.xojo_code;&h7DC607FF;&h58EA2FFF;false
-Class=CreateApp;Sub Applications/CreateApp.xojo_code;&h629A87FF;&h58EA2FFF;false
-Class=DeleteVersionApp;Sub Applications/DeleteVersionApp.xojo_code;&h518477FF;&h58EA2FFF;false
-Class=EditVersionApp;Sub Applications/EditVersionApp.xojo_code;&h39BFF7FF;&h58EA2FFF;false
-Class=ExportApp;Sub Applications/ExportApp.xojo_code;&h34271FFF;&h58EA2FFF;false
-Class=GetKeyApp;Sub Applications/GetKeyApp.xojo_code;&h475957FF;&h58EA2FFF;false
-Class=ListVersionsApp;Sub Applications/ListVersionsApp.xojo_code;&h8ED2FFF;&h58EA2FFF;false
-Class=VersionInfoApp;Sub Applications/VersionInfoApp.xojo_code;&h788B8FFF;&h58EA2FFF;false
-Class=Option;../Other Classes/OptionParser/Option.xojo_code;&h739D11C7;&h797A37FF;false
-Class=OptionInvalidKeyValueException;../Other Classes/OptionParser/OptionInvalidKeyValueException.xojo_code;&h72B88CF5;&h797A37FF;false
-Class=OptionMissingKeyException;../Other Classes/OptionParser/OptionMissingKeyException.xojo_code;&h44C7F771;&h797A37FF;false
-Class=OptionParser;../Other Classes/OptionParser/OptionParser.xojo_code;&h25CD9122;&h797A37FF;false
-Class=OptionParserException;../Other Classes/OptionParser/OptionParserException.xojo_code;&h5CB2B525;&h797A37FF;false
-Class=OptionUnrecognizedKeyException;../Other Classes/OptionParser/OptionUnrecognizedKeyException.xojo_code;&h12104F75;&h797A37FF;false
+OrigIDEVersion=00000000
+Class=App;App.xojo_code;&h0000000031FD87FF;&h0000000000000000;false
+Folder=Custom Plist;../Custom Plist;&h00000000291C0FFF;&h0000000000000000;false
+Module=FormatCodePreferences;FormatCodePreferences.xojo_code;&h000000002977F6F1;&h0000000000000000;false
+BuildSteps=Build Automation;Build Automation.xojo_code;&h0000000028989FFF;&h0000000000000000;false
+Folder=Kaju Classes;../Kaju Classes;&h000000002570CF64;&h0000000000000000;false
+Class=KajuFile;../Admin Classes/KajuFile.xojo_code;&h000000001A7FF7FF;&h0000000000000000;false
+Folder=Other Classes;../Other Classes;&h000000000F6057FF;&h0000000000000000;false
+Class=SubApplication;SubApplication.xojo_code;&h000000002E4257FF;&h0000000000000000;false
+Class=FileHandlerSubApplication;FileHandlerSubApplication.xojo_code;&h000000006664E7FF;&h0000000000000000;false
+Class=VersionHandlerSubApplication;VersionHandlerSubApplication.xojo_code;&h000000002332B7FF;&h0000000000000000;false
+Folder=OptionParser;../Other Classes/OptionParser;&h00000000797A37FF;&h000000000F6057FF;false
+Module=Kaju;../Kaju Classes/Kaju.xojo_code;&h0000000011400316;&h000000002570CF64;false
+Class=KajuException;../Kaju Classes/Kaju/KajuException.xojo_code;&h000000003047231F;&h0000000011400316;false
+Class=UpdateInformation;../Kaju Classes/Kaju/UpdateInformation.xojo_code;&h0000000079AE1ADC;&h0000000011400316;false
+Class=BinaryInformation;../Kaju Classes/Kaju/BinaryInformation.xojo_code;&h000000000E8D70B5;&h0000000011400316;false
+Class=Information;../Kaju Classes/Kaju/Information.xojo_code;&h000000006497A7C4;&h0000000011400316;false
+Module=KajuLocale;../Kaju Classes/KajuLocale.xojo_code;&h00000000020D2554;&h000000002570CF64;false
+Folder=Sub Applications;Sub Applications;&h0000000058EA2FFF;&h0000000000000000;false
+Class=AddVersionApp;Sub Applications/AddVersionApp.xojo_code;&h000000007DC607FF;&h0000000058EA2FFF;false
+Class=CreateApp;Sub Applications/CreateApp.xojo_code;&h00000000629A87FF;&h0000000058EA2FFF;false
+Class=DeleteVersionApp;Sub Applications/DeleteVersionApp.xojo_code;&h00000000518477FF;&h0000000058EA2FFF;false
+Class=EditVersionApp;Sub Applications/EditVersionApp.xojo_code;&h0000000039BFF7FF;&h0000000058EA2FFF;false
+Class=ExportApp;Sub Applications/ExportApp.xojo_code;&h0000000034271FFF;&h0000000058EA2FFF;false
+Class=GetKeyApp;Sub Applications/GetKeyApp.xojo_code;&h00000000475957FF;&h0000000058EA2FFF;false
+Class=ListVersionsApp;Sub Applications/ListVersionsApp.xojo_code;&h0000000008ED2FFF;&h0000000058EA2FFF;false
+Class=VersionInfoApp;Sub Applications/VersionInfoApp.xojo_code;&h00000000788B8FFF;&h0000000058EA2FFF;false
+Class=Option;../Other Classes/OptionParser/Option.xojo_code;&h00000000739D11C7;&h00000000797A37FF;false
+Class=OptionInvalidKeyValueException;../Other Classes/OptionParser/OptionInvalidKeyValueException.xojo_code;&h0000000072B88CF5;&h00000000797A37FF;false
+Class=OptionMissingKeyException;../Other Classes/OptionParser/OptionMissingKeyException.xojo_code;&h0000000044C7F771;&h00000000797A37FF;false
+Class=OptionParser;../Other Classes/OptionParser/OptionParser.xojo_code;&h0000000025CD9122;&h00000000797A37FF;false
+Class=OptionParserException;../Other Classes/OptionParser/OptionParserException.xojo_code;&h000000005CB2B525;&h00000000797A37FF;false
+Class=OptionUnrecognizedKeyException;../Other Classes/OptionParser/OptionUnrecognizedKeyException.xojo_code;&h0000000012104F75;&h00000000797A37FF;false
+Plist=Info;../Custom Plist/Info.plist;&h000000006407F7FF;&h00000000291C0FFF;false
MajorVersion=2
-MinorVersion=0
+MinorVersion=1
SubVersion=0
NonRelease=0
Release=3
InfoVersion=
-LongVersion=v.2.0
-ShortVersion=2.0
+LongVersion=v.2.1
+ShortVersion=2.1
WinCompanyName=MacTechnologies Consulting
WinInternalName=kaju
WinProductName=Kaju CLI
@@ -63,4 +66,9 @@ UseGDIPlus=False
UseBuildsFolder=True
CopyRedistNextToWindowsEXE=False
IsWebProject=False
+LinuxBuildArchitecture=1
+MacBuildArchitecture=1
+WindowsBuildArchitecture=1
OptimizationLevel=0
+WindowsVersions={35138b9a-5d96-4fbd-8e2d-a2440225f93a}|{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}|{1f676c76-80e1-4239-95bb-83d0f6d0da78}|{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}
+WindowsRunAs=0
diff --git a/Kaju Admin CLI/Sub Applications/AddVersionApp.xojo_code b/Kaju Admin CLI/Sub Applications/AddVersionApp.xojo_code
index 0180ba3..f3d3080 100644
--- a/Kaju Admin CLI/Sub Applications/AddVersionApp.xojo_code
+++ b/Kaju Admin CLI/Sub Applications/AddVersionApp.xojo_code
@@ -62,13 +62,17 @@ Inherits VersionHandlerSubApplication
#tag ViewBehavior
#tag ViewProperty
Name="AdditionalHelp"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
#tag ViewProperty
Name="Description"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
@@ -78,6 +82,7 @@ Inherits VersionHandlerSubApplication
Group="ID"
InitialValue="-2147483648"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Left"
@@ -85,18 +90,23 @@ Inherits VersionHandlerSubApplication
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Top"
@@ -104,10 +114,13 @@ Inherits VersionHandlerSubApplication
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Usage"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
diff --git a/Kaju Admin CLI/Sub Applications/CreateApp.xojo_code b/Kaju Admin CLI/Sub Applications/CreateApp.xojo_code
index a6bd54f..409016c 100644
--- a/Kaju Admin CLI/Sub Applications/CreateApp.xojo_code
+++ b/Kaju Admin CLI/Sub Applications/CreateApp.xojo_code
@@ -54,13 +54,17 @@ Inherits SubApplication
#tag ViewBehavior
#tag ViewProperty
Name="AdditionalHelp"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
#tag ViewProperty
Name="Description"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
@@ -70,6 +74,7 @@ Inherits SubApplication
Group="ID"
InitialValue="-2147483648"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Left"
@@ -77,18 +82,23 @@ Inherits SubApplication
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Top"
@@ -96,10 +106,13 @@ Inherits SubApplication
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Usage"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
diff --git a/Kaju Admin CLI/Sub Applications/DeleteVersionApp.xojo_code b/Kaju Admin CLI/Sub Applications/DeleteVersionApp.xojo_code
index 2e5d3f6..f5d1c2e 100644
--- a/Kaju Admin CLI/Sub Applications/DeleteVersionApp.xojo_code
+++ b/Kaju Admin CLI/Sub Applications/DeleteVersionApp.xojo_code
@@ -39,13 +39,17 @@ Inherits VersionHandlerSubApplication
#tag ViewBehavior
#tag ViewProperty
Name="AdditionalHelp"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
#tag ViewProperty
Name="Description"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
@@ -55,6 +59,7 @@ Inherits VersionHandlerSubApplication
Group="ID"
InitialValue="-2147483648"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Left"
@@ -62,18 +67,23 @@ Inherits VersionHandlerSubApplication
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Top"
@@ -81,10 +91,13 @@ Inherits VersionHandlerSubApplication
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Usage"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
diff --git a/Kaju Admin CLI/Sub Applications/EditVersionApp.xojo_code b/Kaju Admin CLI/Sub Applications/EditVersionApp.xojo_code
index eddb87c..f8b9cc3 100644
--- a/Kaju Admin CLI/Sub Applications/EditVersionApp.xojo_code
+++ b/Kaju Admin CLI/Sub Applications/EditVersionApp.xojo_code
@@ -279,13 +279,17 @@ Inherits VersionHandlerSubApplication
#tag ViewBehavior
#tag ViewProperty
Name="AdditionalHelp"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
#tag ViewProperty
Name="Description"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
@@ -295,6 +299,7 @@ Inherits VersionHandlerSubApplication
Group="ID"
InitialValue="-2147483648"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Left"
@@ -302,18 +307,23 @@ Inherits VersionHandlerSubApplication
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Top"
@@ -321,10 +331,13 @@ Inherits VersionHandlerSubApplication
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Usage"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
diff --git a/Kaju Admin CLI/Sub Applications/ExportApp.xojo_code b/Kaju Admin CLI/Sub Applications/ExportApp.xojo_code
index e9c1724..5a8f570 100644
--- a/Kaju Admin CLI/Sub Applications/ExportApp.xojo_code
+++ b/Kaju Admin CLI/Sub Applications/ExportApp.xojo_code
@@ -46,13 +46,17 @@ Inherits FileHandlerSubApplication
#tag ViewBehavior
#tag ViewProperty
Name="AdditionalHelp"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
#tag ViewProperty
Name="Description"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
@@ -62,6 +66,7 @@ Inherits FileHandlerSubApplication
Group="ID"
InitialValue="-2147483648"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Left"
@@ -69,18 +74,23 @@ Inherits FileHandlerSubApplication
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Top"
@@ -88,10 +98,13 @@ Inherits FileHandlerSubApplication
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Usage"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
diff --git a/Kaju Admin CLI/Sub Applications/GetKeyApp.xojo_code b/Kaju Admin CLI/Sub Applications/GetKeyApp.xojo_code
index 9456a0e..bac3fcb 100644
--- a/Kaju Admin CLI/Sub Applications/GetKeyApp.xojo_code
+++ b/Kaju Admin CLI/Sub Applications/GetKeyApp.xojo_code
@@ -34,13 +34,17 @@ Inherits FileHandlerSubApplication
#tag ViewBehavior
#tag ViewProperty
Name="AdditionalHelp"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
#tag ViewProperty
Name="Description"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
@@ -50,6 +54,7 @@ Inherits FileHandlerSubApplication
Group="ID"
InitialValue="-2147483648"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Left"
@@ -57,18 +62,23 @@ Inherits FileHandlerSubApplication
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Top"
@@ -76,10 +86,13 @@ Inherits FileHandlerSubApplication
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Usage"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
diff --git a/Kaju Admin CLI/Sub Applications/ListVersionsApp.xojo_code b/Kaju Admin CLI/Sub Applications/ListVersionsApp.xojo_code
index 7dad2c2..9338911 100644
--- a/Kaju Admin CLI/Sub Applications/ListVersionsApp.xojo_code
+++ b/Kaju Admin CLI/Sub Applications/ListVersionsApp.xojo_code
@@ -121,13 +121,17 @@ Inherits FileHandlerSubApplication
#tag ViewBehavior
#tag ViewProperty
Name="AdditionalHelp"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
#tag ViewProperty
Name="Description"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
@@ -137,6 +141,7 @@ Inherits FileHandlerSubApplication
Group="ID"
InitialValue="-2147483648"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Left"
@@ -144,18 +149,23 @@ Inherits FileHandlerSubApplication
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Top"
@@ -163,10 +173,13 @@ Inherits FileHandlerSubApplication
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Usage"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
diff --git a/Kaju Admin CLI/Sub Applications/VersionInfoApp.xojo_code b/Kaju Admin CLI/Sub Applications/VersionInfoApp.xojo_code
index ef7e319..f0eda5a 100644
--- a/Kaju Admin CLI/Sub Applications/VersionInfoApp.xojo_code
+++ b/Kaju Admin CLI/Sub Applications/VersionInfoApp.xojo_code
@@ -79,13 +79,17 @@ Inherits VersionHandlerSubApplication
#tag ViewBehavior
#tag ViewProperty
Name="AdditionalHelp"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
#tag ViewProperty
Name="Description"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
@@ -95,6 +99,7 @@ Inherits VersionHandlerSubApplication
Group="ID"
InitialValue="-2147483648"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Left"
@@ -102,18 +107,23 @@ Inherits VersionHandlerSubApplication
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Top"
@@ -121,10 +131,13 @@ Inherits VersionHandlerSubApplication
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Usage"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
diff --git a/Kaju Admin CLI/VersionHandlerSubApplication.xojo_code b/Kaju Admin CLI/VersionHandlerSubApplication.xojo_code
index c454991..86d5c22 100644
--- a/Kaju Admin CLI/VersionHandlerSubApplication.xojo_code
+++ b/Kaju Admin CLI/VersionHandlerSubApplication.xojo_code
@@ -46,13 +46,17 @@ Inherits FileHandlerSubApplication
#tag ViewBehavior
#tag ViewProperty
Name="AdditionalHelp"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
#tag ViewProperty
Name="Description"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
@@ -62,6 +66,7 @@ Inherits FileHandlerSubApplication
Group="ID"
InitialValue="-2147483648"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Left"
@@ -69,18 +74,23 @@ Inherits FileHandlerSubApplication
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Top"
@@ -88,10 +98,13 @@ Inherits FileHandlerSubApplication
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Usage"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
diff --git a/Kaju Classes/Kaju.xojo_code b/Kaju Classes/Kaju.xojo_code
index a83f539..53fddb0 100644
--- a/Kaju Classes/Kaju.xojo_code
+++ b/Kaju Classes/Kaju.xojo_code
@@ -225,101 +225,29 @@ Protected Module Kaju
End Sub
#tag EndMethod
- #tag Method, Flags = &h1, CompatibilityFlags = (TargetWeb and (Target32Bit or Target64Bit)) or (TargetDesktop and (Target32Bit or Target64Bit)) or (TargetIOS and (Target32Bit or Target64Bit))
- Protected Function ProcessReleaseNotes(notes As String) As String
- //
- // The release notes might be straight HTML or them might be a URL.
- // If the latter, the remainder will be alternate notes.
- // This method will determine which it is and, if the latter, will
- // attempt to fetch the notes. If it can't, it will return the alternate
- // notes if any, or a message.
- //
- // The URL may start the first line followed by an EOL or may be in an
- // HTML comment that starts the first line. The latter form will maintain
- // better compatibility with previous versions of Kaju.
- //
- // Examples:
- //
- // http://something.com/UpdateInformation.json
- //
- //
+ #tag Method, Flags = &h1, CompatibilityFlags = (TargetHasGUI)
+ Protected Sub StartUpdate(initiater As Kaju.UpdateInitiater)
+ App.UpdateInitiater = initiater
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h21
+ Private Function StripURLCredentials(url As String) As String
//
- //
+ // Strips credentials from the given url
//
- static noInfoHTML as string = "" + KajuLocale.kNoUpdateInfoMessage + ""
-
- static rxURLSplitter as RegEx
- if rxURLSplitter is nil then
- rxURLSplitter = new RegEx
- rxURLSplitter.SearchPattern = _
- "(?mi-Us)\A\x20*(?|(?:(http[^\s]+)\x20*\R)|(?:))([\s\S]*)"
- end if
-
- dim r as string = notes
+ dim rx as new RegEx
+ rx.SearchPattern = "(://|^)(\w+:\w*)@"
+ rx.ReplacementPattern = "$1"
- dim matchURL as RegExMatch = rxURLSplitter.Search( notes)
- if matchURL isa RegExMatch then
- dim url as string = matchURL.SubExpressionString( 1 ).Trim
- dim alternateNotes as string = matchURL.SubExpressionString( 2 ).Trim
-
- dim redirector as new Kaju.HTTPSSocket
- url = redirector.GetRedirectAddress( url, 5 )
-
- dim http as new Kaju.HTTPSSocket
- dim raw as string = http.Get( url, 5 )
- if http.HTTPStatusCode = 404 or raw.Trim = "" then
- r = alternateNotes
- else
- //
- // Adjust the encoding
- //
-
- dim enc as TextEncoding
-
- //
- // See if the html contains a charset
- //
- static rxCharSetFinder as RegEx
- if rxCharSetFinder is nil then
- rxCharSetFinder = new RegEx
- rxCharSetFinder.SearchPattern = " "" then
- url = headers.Value( "Location" )
- else
- exit
- end if
- if isFinite then
- maximumIterations = maximumIterations - 1
- end if
- loop until isFinite and maximumIterations = 0 // Will never end if maxiumIterations < 0 to start
-
- return url.Trim
-
- End Function
- #tag EndMethod
-
#tag Method, Flags = &h0
Sub SendRequest(method As String, url As String)
SetSecure( url )
@@ -133,20 +99,23 @@ Inherits HTTPSecureSocket
self.Port = 80
end if
+ SetRequestHeader "Cache-Control", "private, no-cache, max-age=0"
+ SetRequestHeader "Pragma", "no-cache"
+
//
// See if the username and password has been specified
//
dim rx as new RegEx
- rx.SearchPattern = "^(?:https?://)([^:/\x20@]+):([^:/\x20@]*)@(.*)"
+ rx.SearchPattern = "^(https?://)([^:/\x20@]+):([^:/\x20@]*)@(.*)"
dim match as RegExMatch = rx.Search( url )
if match is nil then
Username = ""
Password = ""
else
- Username = DecodeURLComponent( match.SubExpressionString( 1 ) )
- Password = DecodeURLComponent( match.SubExpressionString( 2 ) )
- url = match.SubExpressionString( 3 )
+ Username = DecodeURLComponent( match.SubExpressionString( 2 ) )
+ Password = DecodeURLComponent( match.SubExpressionString( 3 ) )
+ url = match.SubExpressionString( 1 ) + match.SubExpressionString( 4 )
end if
End Sub
@@ -176,76 +145,83 @@ Inherits HTTPSecureSocket
#tag ViewBehavior
+ #tag ViewProperty
+ Name="SSLConnectionType"
+ Visible=true
+ Group="Behavior"
+ InitialValue="3"
+ Type="SSLConnectionTypes"
+ EditorType="Enum"
+ #tag EnumValues
+ "1 - SSLv23"
+ "3 - TLSv1"
+ "4 - TLSv11"
+ "5 - TLSv12"
+ #tag EndEnumValues
+ #tag EndViewProperty
#tag ViewProperty
Name="CertificateFile"
Visible=true
Group="Behavior"
+ InitialValue=""
Type="FolderItem"
- EditorType="File"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="CertificatePassword"
Visible=true
Group="Behavior"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="CertificateRejectionFile"
Visible=true
Group="Behavior"
+ InitialValue=""
Type="FolderItem"
- EditorType="File"
- #tag EndViewProperty
- #tag ViewProperty
- Name="ConnectionType"
- Visible=true
- Group="Behavior"
- InitialValue="3"
- Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="ForceSecure"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Index"
Visible=true
Group="ID"
+ InitialValue=""
Type="Integer"
- EditorType="Integer"
- #tag EndViewProperty
- #tag ViewProperty
- Name="Left"
- Visible=true
- Group="Position"
- Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
- EditorType="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Secure"
Visible=true
Group="Behavior"
+ InitialValue=""
Type="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
- EditorType="String"
- #tag EndViewProperty
- #tag ViewProperty
- Name="Top"
- Visible=true
- Group="Position"
- Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag EndViewBehavior
End Class
diff --git a/Kaju Classes/Kaju/HTTPSocketAsync.xojo_code b/Kaju Classes/Kaju/HTTPSocketAsync.xojo_code
new file mode 100644
index 0000000..89d55fd
--- /dev/null
+++ b/Kaju Classes/Kaju/HTTPSocketAsync.xojo_code
@@ -0,0 +1,235 @@
+#tag Class
+Protected Class HTTPSocketAsync
+Inherits URLConnection
+ #tag Event
+ Function AuthenticationRequested(realm As String, ByRef name As String, ByRef password As String) As Boolean
+ if RaiseEvent AuthenticationRequested( realm, name, password ) then
+ return true
+ end if
+
+ if Username <> "" then
+ name = Username.ToText
+ password = self.Password.ToText
+ return true
+ else
+ return false
+ end if
+ End Function
+ #tag EndEvent
+
+ #tag Event
+ Sub ContentReceived(URL As String, HTTPStatus As Integer, content As String)
+ url = Kaju.StripURLCredentials( url )
+
+ if not AllowRedirection and url <> RequestedURL then
+ content = ""
+ httpStatus = 302
+
+ elseif content.Encoding is nil and Encodings.UTF8.IsValidData( content ) then
+ content = content.DefineEncoding( Encodings.UTF8 )
+
+ end if
+
+ RaiseEvent ContentReceived( url, httpStatus, content )
+ End Sub
+ #tag EndEvent
+
+
+ #tag Method, Flags = &h0
+ Sub Get(url As String, allowRedirect As Boolean)
+ self.AllowRedirection = allowRedirect
+
+ Disconnect
+
+ SetSecure url
+ super.Send "GET", url
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub Get(url As String, file As FolderItem, allowRedirect As Boolean)
+ self.AllowRedirection = allowRedirect
+
+ Disconnect
+
+ SetSecure url
+ super.Send "GET", url, file
+
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub GetSync(url As String, file As FolderItem, timeout As Integer = 0)
+ self.AllowRedirection = true
+
+ Disconnect
+
+ SetSecure url
+ super.SendSync "GET", url, file, timeout
+
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function GetSync(url As String, timeout As Integer = 0) As String
+ self.AllowRedirection = true
+
+ Disconnect
+
+ SetSecure url
+ return super.SendSync( "GET", url, timeout )
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h21
+ Private Sub Send(method As String, url As String, File As FolderItem)
+ super.Send Method, URL, File
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h21
+ Private Sub Send(method as Text, url as Text)
+ super.Send method, url
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h21
+ Private Sub SendSync(method As String, URL As String, file As FolderItem, timeout As Integer = 0)
+ super.SendSync method, URL, file, timeout
+
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h21
+ Private Function SendSync(method As String, URL As String, timeout As Integer = 0) As String
+ return super.SendSync( method, URL, timeout )
+
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h21
+ Private Sub SetSecure(ByRef url As String)
+ AllowCertificateValidation = true
+ Username = ""
+ Password = ""
+ ClearRequestHeaders
+
+ RequestHeader( "Cache-Control" ) = "private, no-cache, max-age=0"
+ RequestHeader( "Pragma" ) = "no-cache"
+
+ url = url.ConvertEncoding( Encodings.UTF8 )
+ RequestedURL = Kaju.StripURLCredentials( url )
+
+ #if not TargetMacOS then
+
+ //
+ // See if the username and password has been specified
+ //
+ dim rx as new RegEx
+ rx.SearchPattern = "^(https?://)([^:/\x20@]+):([^:/\x20@]*)@(.*)"
+
+ dim match as RegExMatch = rx.Search( url )
+ if match isa RegExMatch then
+ Username = DecodeURLComponent( match.SubExpressionString( 2 ) ).DefineEncoding( Encodings.UTF8 )
+ Password = DecodeURLComponent( match.SubExpressionString( 3 ) ).DefineEncoding( Encodings.UTF8 )
+ url = match.SubExpressionString( 1 ) + match.SubExpressionString( 4 )
+ url = url.DefineEncoding( Encodings.UTF8 )
+
+ //
+ // Set the request header manually
+ //
+ dim encoded as string = EncodeBase64( Username + ":" + Password ).DefineEncoding( Encodings.UTF8 )
+ RequestHeader( "Authorization" ) = "Basic " + encoded.ToText
+ end if
+
+ #endif
+ End Sub
+ #tag EndMethod
+
+
+ #tag Hook, Flags = &h0
+ Event AuthenticationRequested(realm As String, ByRef name As String, ByRef password As String) As Boolean
+ #tag EndHook
+
+ #tag Hook, Flags = &h0
+ Event ContentReceived(url As String, httpStatus As Integer, content As String)
+ #tag EndHook
+
+
+ #tag Property, Flags = &h21
+ Private AllowRedirection As Boolean = False
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private Password As String
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private RequestedURL As String
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private Username As String
+ #tag EndProperty
+
+
+ #tag ViewBehavior
+ #tag ViewProperty
+ Name="AllowCertificateValidation"
+ Visible=false
+ Group="Behavior"
+ InitialValue=""
+ Type="Boolean"
+ EditorType=""
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="HTTPStatusCode"
+ Visible=false
+ Group="Behavior"
+ InitialValue=""
+ Type="Integer"
+ EditorType=""
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Index"
+ Visible=true
+ Group="ID"
+ InitialValue="-2147483648"
+ Type="Integer"
+ EditorType=""
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Left"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ EditorType=""
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Name"
+ Visible=true
+ Group="ID"
+ InitialValue=""
+ Type="String"
+ EditorType=""
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Super"
+ Visible=true
+ Group="ID"
+ InitialValue=""
+ Type="String"
+ EditorType=""
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Top"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ EditorType=""
+ #tag EndViewProperty
+ #tag EndViewBehavior
+End Class
+#tag EndClass
diff --git a/Kaju Classes/Kaju/Information.xojo_code b/Kaju Classes/Kaju/Information.xojo_code
index 6097e7a..dce5980 100644
--- a/Kaju Classes/Kaju/Information.xojo_code
+++ b/Kaju Classes/Kaju/Information.xojo_code
@@ -132,7 +132,7 @@ Protected Class Information
dim props() as Introspection.PropertyInfo = ti.GetProperties
for each prop as Introspection.PropertyInfo in props
- if prop.IsShared or prop.IsComputed or not prop.CanRead or not prop.CanWrite or not prop.IsPublic then
+ if prop.IsShared or not prop.CanRead or not prop.CanWrite or not prop.IsPublic then
continue for prop
end if
@@ -203,11 +203,15 @@ Protected Class Information
Group="ID"
InitialValue="-2147483648"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="IsValid"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Left"
@@ -215,18 +219,23 @@ Protected Class Information
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Top"
@@ -234,6 +243,7 @@ Protected Class Information
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag EndViewBehavior
End Class
diff --git a/Kaju Classes/Kaju/KajuException.xojo_code b/Kaju Classes/Kaju/KajuException.xojo_code
index 4205df8..e8d69fd 100644
--- a/Kaju Classes/Kaju/KajuException.xojo_code
+++ b/Kaju Classes/Kaju/KajuException.xojo_code
@@ -35,9 +35,11 @@ Inherits RuntimeException
#tag ViewBehavior
#tag ViewProperty
Name="ErrorNumber"
+ Visible=false
Group="Behavior"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Index"
@@ -45,6 +47,7 @@ Inherits RuntimeException
Group="ID"
InitialValue="-2147483648"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Left"
@@ -52,10 +55,13 @@ Inherits RuntimeException
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Message"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
@@ -63,18 +69,25 @@ Inherits RuntimeException
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Reason"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="Text"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Top"
@@ -82,6 +95,7 @@ Inherits RuntimeException
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag EndViewBehavior
End Class
diff --git a/Kaju Classes/Kaju/UpdateChecker.xojo_code b/Kaju Classes/Kaju/UpdateChecker.xojo_code
index e47d06f..7721a3c 100644
--- a/Kaju Classes/Kaju/UpdateChecker.xojo_code
+++ b/Kaju Classes/Kaju/UpdateChecker.xojo_code
@@ -1,5 +1,55 @@
#tag Class
Protected Class UpdateChecker
+ #tag Method, Flags = &h21
+ Private Sub AsyncHTTP_ContentReceived(sender As HTTPSocketAsync, url As String, httpStatus As Integer, content As String)
+ #pragma unused sender
+ #pragma unused url
+
+ RemoveInstance self
+
+ dim statusCode as integer = httpStatus
+ dim raw as string = content
+
+ if statusCode >= 400 and statusCode <= 499 then // Not found
+ mResult = ResultType.PageNotFound
+ RaiseEvent ExecuteAsyncComplete
+
+ elseif statusCode >= 300 and statusCode <= 399 then
+ mResult = ResultType.PageRedirected
+ RaiseEvent ExecuteAsyncComplete
+
+ elseif ProcessRaw( raw ) then
+ FetchAsync true // Immediate because the socket is already set up
+
+ else
+ RaiseEvent ExecuteAsyncComplete
+
+ end if
+
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h21
+ Private Sub AsyncHTTP_Error(sender As HTTPSocketAsync, err As RuntimeException)
+ #pragma unused sender
+
+ RemoveInstance self
+
+ dim errMsg as string = err.Message
+ if errMsg = "" then
+ err.Message = "An exception of type " + Introspection.GetType( err ).Name + " has occurred"
+ end if
+
+ LastError = err
+
+ if HandleError( errMsg ) then
+ FetchAsync true // Immediate because the socket is already set up
+ else
+ RaiseEvent ExecuteAsyncComplete
+ end if
+ End Sub
+ #tag EndMethod
+
#tag Method, Flags = &h0
Sub Constructor(preferencesFolder As FolderItem, preferencesFilename As String = kDefaultPreferencesName)
self.PrefFile = preferencesFolder.Child( preferencesFilename )
@@ -12,6 +62,15 @@ Protected Class UpdateChecker
#tag Method, Flags = &h21
Private Sub Destructor()
SavePrefs()
+
+ TeardownAsyncHTTP
+
+ if FetchAsyncTimer isa object then
+ FetchAsyncTimer.Mode = Timer.ModeOff
+ RemoveHandler FetchAsyncTimer.Action, WeakAddressOf FetchAsyncTimer_Action
+ FetchAsyncTimer = nil
+ end if
+
End Sub
#tag EndMethod
@@ -22,122 +81,150 @@ Protected Class UpdateChecker
#tag EndMethod
#tag Method, Flags = &h0
- Sub Execute()
+ Attributes( Deprecated = "ExecuteAsync" ) Sub Execute()
// Pull the data from the URL, check it, and preset the window if needed
// Returns true if the app should quit in preparation of the update.
//
// The caller should be prepared to handle an exception in case of error.
-
- //
- // If there is already an update in progress, do nothing
//
- if UpdateWindowIsOpen then
- mResult = ResultType.UpdateAlreadyInProgress
- return
- end if
- //
- // Make sure the OS is supported
- //
- if not OSIsSupported() then
- mResult = ResultType.UnsupportedOS
+ if not PreCheck then
return
end if
+ FetchAndProcess
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub ExecuteAsync()
//
- // Check for write permission
+ // Uses the new socket to check asynchronously
+ // (required for newer certificates)
//
- if true then // Scope
-
- dim executable as FolderItem = Kaju.TrueExecutableFile
-
- #if TargetMacOS then
- if not executable.Parent.IsWriteable or not Kaju.IsWriteableRecursive( executable ) then
- mResult = ResultType.NoWritePermission
- return
- end if
- #else
- if not Kaju.IsWriteableRecursive( executable.Parent ) then
- mResult = ResultType.NoWritePermission
- return
- end if
- #endif
-
- end if
-
- mDryRun = false
-
- //
- // Make sure we have some URL
+ // The caller should be prepared to handle an exception in case of error.
//
- if UpdateURL.Trim = "" then
- raise new KajuException( KajuException.kErrorMissingUpdateURL, CurrentMethodName )
+ if not PreCheck then
+ return
end if
+ FetchAsync false
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h21
+ Private Sub FetchAndProcess()
//
// Look for redirection
//
dim url as string = self.UpdateURL
- if AllowRedirection then
- dim redirector as new Kaju.HTTPSSocket
- url = redirector.GetRedirectAddress( url, 5 )
- end if
//
// Repeat the check until we get data or the user gives up
//
do
+ const kTimeout as integer = 5
- dim http as new Kaju.HTTPSSocket
+ dim raw as string
+ dim statusCode as integer
- dim raw as string = http.Get( url, 5 )
- if http.HTTPStatusCode = 404 then // Not found
- mResult = ResultType.NoUpdateAvailable
+ //
+ // Note:
+ //
+ // If Xojo ever disallows redirection in URLConnection
+ // we can delete HTTPSSocket and simplify this
+ // code.
+ //
+ if AllowRedirection then
+ dim http as new Kaju.HTTPSocketAsync // Follows redirects anyway
+ raw = http.GetSync( url, kTimeout )
+ statusCode = http.HTTPStatusCode
+ else
+ dim http as new Kaju.HTTPSSocket
+ raw = http.Get( url, kTimeout ) // Does not follow redirects
+ statusCode = http.HTTPStatusCode
+ end if
+
+ if statusCode = 404 then // Not found
+ mResult = ResultType.PageNotFound
exit do
- elseif raw = "" then
- if HandleError( KajuLocale.kErrorNoUpdateData ) then
- continue do
- else
- exit do
- end if
+ elseif statusCode >= 300 and statusCode <= 399 then
+ mResult = ResultType.PageRedirected
+ exit do
+ end if
+
+ if not ProcessRaw( raw ) then
+ exit do
end if
+ loop
+
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h21
+ Private Sub FetchAsync(immediate As Boolean)
+ dim http as Kaju.HTTPSocketAsync = GetNewAsyncHTTPSocket // Set up the socket
+
+ mResult = ResultType.FetchingUpdateInfo
+
+ //
+ // We have to hold a reference to this object in case the consumer decided to use
+ // a temporary variable
+ //
+ StoreInstance self
+
+ //
+ // If not immediate, start a timer to do this
+ //
+ // This is to counter a potential timing issue reported by a user
+ // so we set up the socket first, then call it later
+ //
+ if immediate then
- raw = raw.DefineEncoding( Encodings.UTF8 )
+ dim url as string = UpdateURL
+ http.Get url, AllowRedirection
- dim firstLine as string
- dim remainder as string
- SeparatePacket( raw, firstLine, remainder )
- raw = remainder
+ //
+ // Processing will resume in the events
+ //
- dim sig as string = firstLine.Left( kUpdatePacketMarker.Len )
- if StrComp( sig, kUpdatePacketMarker, 0 ) <> 0 then
- if HandleError( KajuLocale.kErrorIncorrectPacketMarker ) then
- continue do
- else
- exit do
- end if
- end if
+ else
- sig = firstLine.Mid( sig.Len + 1 )
- sig = DecodeHex( sig )
- if not Crypto.RSAVerifySignature( raw, sig, ServerPublicRSAKey ) then
- if HandleError( KajuLocale.kErrorIncorrectPacketSignature ) then
- continue do
- else
- exit do
- end if
+ if FetchAsyncTimer is nil then
+ FetchAsyncTimer = new Timer
+ FetchAsyncTimer.Period = 10
+ AddHandler FetchAsyncTimer.Action, WeakAddressOf FetchAsyncTimer_Action
end if
- if ProcessUpdateData( raw ) then
- exit do
- end if
- loop
+ FetchAsyncTimer.Mode = Timer.ModeSingle
+
+ end if
End Sub
#tag EndMethod
+ #tag Method, Flags = &h21
+ Private Sub FetchAsyncTimer_Action(sender As Timer)
+ #pragma unused sender
+ FetchAsync true
+
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h21
+ Private Function GetNewAsyncHTTPSocket() As Kaju.HTTPSocketAsync
+ TeardownAsyncHTTP
+
+ AsyncHTTP = new HTTPSocketAsync
+ AddHandler AsyncHTTP.ContentReceived, WeakAddressOf AsyncHTTP_ContentReceived
+ AddHandler AsyncHTTP.Error, WeakAddressOf AsyncHTTP_Error
+
+ return AsyncHTTP
+ End Function
+ #tag EndMethod
+
#tag Method, Flags = &h21
Private Function HandleError(msg As String) As Boolean
// Displays a dialog to the user with the message and asks if they want to try again now or later
@@ -255,34 +342,174 @@ Protected Class UpdateChecker
Shared Function OSIsSupported() As Boolean
// Ensures that the right tools are available on the current OS
- dim r as boolean = true // Assume it's fine
+ dim errorCode as integer = 0 // Assume it's fine
+ dim errorMessage as string
- #if TargetMacOS then
-
- r = true // If this app can run, it has the right tools
-
- #elseif TargetWindows then
+ //
+ // Try more than once, just in case
+ //
+ for repeatIndex as integer = 1 to 2
- dim sh as new Shell
- sh.Execute "XCOPY /?"
- r = sh.ErrorCode = 0
+ #if TargetMacOS then
+
+ errorCode = 0 // If this app can run, it has the right tools
+ errorMessage = ""
+
+ #elseif TargetWindows then
+
+ dim sh as new Shell
+ sh.TimeOut = 3000
+ sh.Execute "XCOPY /?"
+ errorCode = sh.ErrorCode
+ if errorCode <> 0 then
+ errorMessage = sh.Result.Trim
+ end if
+
+ #else // Linux
+
+ dim cmds() as string = array( "rsync --version", "/usr/bin/logger --version" )
+
+ dim sh as new shell
+ for each cmd as string in cmds
+ sh.Execute cmd
+ errorCode = sh.ErrorCode
+
+ if errorCode <> 0 then
+ errorMessage = "(" + cmd + ") " + sh.Result.Trim
+ exit for cmd
+ end if
+ next
+
+ #endif
- #else // Linux
+ if errorCode = 0 then
+ exit for repeatIndex
+ else
+ errorMessage = errorMessage.Trim
+ System.Log System.LogLevelCritical, _
+ CurrentMethodName + ": Tool not available, code " + str( errorCode ) + _
+ if( errorMessage <> "", ": " + errorMessage, "" )
+ end if
+ next
+
+ return errorCode = 0
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h21
+ Private Function Precheck() As Boolean
+ //
+ // If there is already an update in progress, do nothing
+ //
+ if UpdateWindowIsOpen then
+ mResult = ResultType.UpdateAlreadyInProgress
+ return false
+ end if
+
+ //
+ // Clear the last error
+ //
+ LastError = nil
+
+ //
+ // Make sure the OS is supported
+ //
+ if not OSIsSupported() then
+ mResult = ResultType.UnsupportedOS
+ return false
+ end if
+
+ //
+ // Check for write permission
+ //
+ if true then // Scope
- dim cmds() as string = array( "rsync --version", "/usr/bin/logger --version" )
+ dim executable as FolderItem = Kaju.TrueExecutableFile
- dim sh as new shell
- for each cmd as string in cmds
- sh.Execute cmd
- if sh.ErrorCode <> 0 then
- r = false
- exit
+ #if TargetMacOS then
+ if not executable.Parent.IsWriteable or not Kaju.IsWriteableRecursive( executable ) then
+ mResult = ResultType.NoWritePermission
+ return false
end if
- next
+ #else
+ if not Kaju.IsWriteableRecursive( executable.Parent ) then
+ mResult = ResultType.NoWritePermission
+ return false
+ end if
+ #endif
- #endif
+ end if
- return r
+ mDryRun = false
+
+ //
+ // Make sure we have some URL
+ //
+
+ if UpdateURL.Trim = "" then
+ raise new KajuException( KajuException.kErrorMissingUpdateURL, CurrentMethodName )
+ end if
+
+ return true
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h21
+ Private Function ProcessRaw(raw As String) As Boolean
+ //
+ // Processes the raw packet
+ //
+ // Returns True if the process should continue, False if it's done
+ // or was cancelled
+ //
+
+ if raw = "" then
+ return HandleError( KajuLocale.kErrorNoUpdateData )
+ end if
+
+ raw = raw.DefineEncoding( Encodings.UTF8 )
+
+ 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
+ return HandleError( KajuLocale.kErrorIncorrectPacketMarker )
+ end if
+
+ sig = firstLine.Mid( sig.Len + 1 ).Trim
+ sig = DecodeHex( sig )
+
+ //
+ // It's possible the EOL in the JSON got changed so we will try all
+ // possibilities before giving up
+ //
+ dim isValid as boolean
+
+ dim eolChars() as string = array( "", &u0A, &u0D, &u0D + &u0A )
+ for each eol as string in eolChars
+ dim tester as string = raw
+ if eol <> "" then
+ tester = ReplaceLineEndings( tester, eol )
+ end if
+
+ isValid = Crypto.RSAVerifySignature( tester, sig, ServerPublicRSAKey )
+ if isValid then
+ exit for eol
+ end if
+ isValid = Crypto.RSAVerifySignature( tester.Trim, sig, ServerPublicRSAKey )
+ if isValid then
+ exit for eol
+ end if
+ next
+
+ if not isValid then
+ return HandleError( KajuLocale.kErrorIncorrectPacketSignature )
+ end if
+
+ return not ProcessUpdateData( raw )
End Function
#tag EndMethod
@@ -302,7 +529,8 @@ Protected Class UpdateChecker
dim info() as Kaju.UpdateInformation
dim updateIsRequired as boolean
for i as integer = 0 to ub
- dim thisInfo as new Kaju.UpdateInformation( j( i ) )
+ dim thisElement as JSONItem = j( i )
+ dim thisInfo as new Kaju.UpdateInformation( thisElement )
//
// See if the binary information is present
@@ -380,17 +608,20 @@ Protected Class UpdateChecker
End Function
#tag EndMethod
- #tag Method, Flags = &h0
- Sub ResetIgnored()
- redim IgnoreVersionsPref( -1 )
+ #tag Method, Flags = &h21
+ Private Shared Sub RemoveInstance(o As UpdateChecker)
+ dim i as integer = AsyncCheckers.IndexOf( o )
+ if i <> -1 then
+ AsyncCheckers.Remove i
+ end if
+
End Sub
#tag EndMethod
#tag Method, Flags = &h0
- Function Result() As ResultType
- return mResult
-
- End Function
+ Sub ResetIgnored()
+ redim IgnoreVersionsPref( -1 )
+ End Sub
#tag EndMethod
#tag Method, Flags = &h21
@@ -454,6 +685,15 @@ Protected Class UpdateChecker
End Sub
#tag EndMethod
+ #tag Method, Flags = &h21
+ Private Shared Sub StoreInstance(o As UpdateChecker)
+ if AsyncCheckers.IndexOf( o ) = -1 then
+ AsyncCheckers.Append o
+ end if
+
+ End Sub
+ #tag EndMethod
+
#tag Method, Flags = &h21
Private Function StringArrayToJSON(arr() As String) As JSONItem
dim j as new JSONItem( "[]" )
@@ -465,6 +705,17 @@ Protected Class UpdateChecker
End Function
#tag EndMethod
+ #tag Method, Flags = &h21
+ Private Sub TeardownAsyncHTTP()
+ if AsyncHTTP isa object then
+ RemoveHandler AsyncHTTP.ContentReceived, WeakAddressOf AsyncHTTP_ContentReceived
+ RemoveHandler AsyncHTTP.Error, WeakAddressOf AsyncHTTP_Error
+ AsyncHTTP = nil
+ end if
+
+ End Sub
+ #tag EndMethod
+
#tag Method, Flags = &h0
Sub TestUpdate(jsonString As String)
// Allows a dry run with the update information that would otherwise be obtained
@@ -491,11 +742,7 @@ Protected Class UpdateChecker
#tag Hook, Flags = &h0
- Event ReadyToInstall()
- #tag EndHook
-
- #tag Hook, Flags = &h0
- Event RequiredUpdateDeclined()
+ Event ExecuteAsyncComplete()
#tag EndHook
@@ -515,6 +762,14 @@ Protected Class UpdateChecker
AllowRedirection As Boolean = False
#tag EndProperty
+ #tag Property, Flags = &h21
+ Private Shared AsyncCheckers() As Kaju.UpdateChecker
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private AsyncHTTP As Kaju.HTTPSocketAsync
+ #tag EndProperty
+
#tag Property, Flags = &h0
DefaultImage As Picture
#tag EndProperty
@@ -523,6 +778,10 @@ Protected Class UpdateChecker
DefaultUseTransparency As Boolean = True
#tag EndProperty
+ #tag Property, Flags = &h21
+ Private FetchAsyncTimer As Timer
+ #tag EndProperty
+
#tag Property, Flags = &h0
HonorIgnored As Boolean = True
#tag EndProperty
@@ -531,12 +790,16 @@ Protected Class UpdateChecker
Private IgnoreVersionsPref() As String
#tag EndProperty
+ #tag Property, Flags = &h0
+ LastError As RuntimeException
+ #tag EndProperty
+
#tag Property, Flags = &h21
Private mDryRun As Boolean
#tag EndProperty
#tag Property, Flags = &h21
- Private mResult As ResultType = ResultType.NotYetChecked
+ Attributes( hidden ) Private mResult As ResultType = ResultType.NotYetChecked
#tag EndProperty
#tag Property, Flags = &h21
@@ -547,6 +810,15 @@ Protected Class UpdateChecker
QuitOnCancelIfRequired As Boolean = True
#tag EndProperty
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ return mResult
+ End Get
+ #tag EndGetter
+ Result As ResultType
+ #tag EndComputedProperty
+
#tag Property, Flags = &h0
ServerPublicRSAKey As String
#tag EndProperty
@@ -600,51 +872,69 @@ Protected Class UpdateChecker
NoUpdateAvailable = 0
IgnoredUpdateAvailable
UpdateAvailable
- RequiredUpdateAvailable
+ RequiredUpdateAvailable
+ FetchingUpdateInfo
+ PageRedirected = 302
+ PageNotFound = 404
#tag EndEnum
#tag ViewBehavior
#tag ViewProperty
Name="Allow32bitTo64bitUpdates"
+ Visible=false
Group="Behavior"
InitialValue="True"
Type="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="AllowedInteraction"
+ Visible=false
Group="Behavior"
InitialValue="kAllowAll"
Type="UInt32"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="AllowedStage"
+ Visible=false
Group="Behavior"
InitialValue="App.Development"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="AllowRedirection"
+ Visible=false
Group="Behavior"
InitialValue="False"
Type="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="DefaultImage"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="Picture"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="DefaultUseTransparency"
+ Visible=false
Group="Behavior"
InitialValue="True"
Type="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="HonorIgnored"
+ Visible=false
Group="Behavior"
InitialValue="True"
Type="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Index"
@@ -652,6 +942,7 @@ Protected Class UpdateChecker
Group="ID"
InitialValue="-2147483648"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Left"
@@ -659,22 +950,29 @@ Protected Class UpdateChecker
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="QuitOnCancelIfRequired"
+ Visible=false
Group="Behavior"
InitialValue="True"
Type="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="ServerPublicRSAKey"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
@@ -682,7 +980,9 @@ Protected Class UpdateChecker
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Top"
@@ -690,17 +990,45 @@ Protected Class UpdateChecker
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="UpdateURL"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
#tag ViewProperty
Name="UpdateWindowIsOpen"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="Boolean"
+ EditorType=""
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Result"
+ Visible=false
+ Group="Behavior"
+ InitialValue=""
+ Type="ResultType"
+ EditorType="Enum"
+ #tag EnumValues
+ "-9999 - NotYetChecked"
+ "-100 - UpdateAlreadyInProgress"
+ "-70 - UnsupportedOS"
+ "-50 - NoWritePermission"
+ "-1 - Error"
+ "0 - NoUpdateAvailable"
+ "1 - IgnoredUpdateAvailable"
+ "2 - UpdateAvailable"
+ "3 - RequiredUpdateAvailable"
+ "4 - FetchingUpdateInfo"
+ "302 - PageRedirected"
+ "404 - PageNotFound"
+ #tag EndEnumValues
#tag EndViewProperty
#tag EndViewBehavior
End Class
diff --git a/Kaju Classes/Kaju/UpdateInformation.xojo_code b/Kaju Classes/Kaju/UpdateInformation.xojo_code
index 94a2248..0a6471b 100644
--- a/Kaju Classes/Kaju/UpdateInformation.xojo_code
+++ b/Kaju Classes/Kaju/UpdateInformation.xojo_code
@@ -115,6 +115,13 @@ Inherits Kaju.Information
Function ConvertToJSON() As JSONItem
dim j as JSONItem = super.ConvertToJSON
+ //
+ // Add a security token
+ //
+ dim rawKey as string = Crypto.GenerateRandomBytes( 8 )
+ dim encodedKey as string = EncodeBase64( rawKey, 0 )
+ j.Value( Kaju.kNameSecurityToken ) = encodedKey
+
for each binaryName as string in BinaryNames
dim b as Kaju.BinaryInformation = Binaries.Lookup( binaryName, nil )
if b isa Kaju.BinaryInformation then
@@ -126,6 +133,24 @@ Inherits Kaju.Information
End Function
#tag EndMethod
+ #tag Method, Flags = &h21
+ Private Sub Destructor()
+ #if not TargetConsole then
+ if ImageSocket isa object then
+ ImageSocket.Disconnect
+ RemoveHandler ImageSocket.ContentReceived, WeakAddressOf ImageSocket_ContentReceived
+ ImageSocket = nil
+ end if
+
+ if ReleaseNotesSocket isa object then
+ ReleaseNotesSocket.Disconnect
+ RemoveHandler ReleaseNotesSocket.ContentReceived, WeakAddressOf ReleaseNotesSocket_ContentReceived
+ ReleaseNotesSocket = nil
+ end if
+ #endif
+ End Sub
+ #tag EndMethod
+
#tag Method, Flags = &h0
Function FetchBinary(binaryName As String) As Kaju.BinaryInformation
dim binary as Kaju.BinaryInformation = Binaries.Lookup( binaryName, nil )
@@ -147,6 +172,75 @@ Inherits Kaju.Information
End Function
#tag EndMethod
+ #tag Method, Flags = &h21, CompatibilityFlags = (TargetWeb and (Target32Bit or Target64Bit)) or (TargetDesktop and (Target32Bit or Target64Bit)) or (TargetIOS and (Target32Bit or Target64Bit))
+ Private Sub ImageSocket_ContentReceived(sender As Kaju.HTTPSocketAsync, url As String, httpStatus As Integer, content As String)
+ #pragma unused sender
+ #pragma unused url
+
+ if httpStatus <> 404 and content <> "" then
+ dim p as Picture = Picture.FromData( content )
+
+ if ImageScale > 1 then
+ p = new Picture( p.Width \ ImageScale, p.Height \ ImageScale, array( p ) )
+ end if
+
+ mImage = p
+ RaiseEvent ImageReceived
+ end if
+
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h21, CompatibilityFlags = (TargetWeb and (Target32Bit or Target64Bit)) or (TargetDesktop and (Target32Bit or Target64Bit)) or (TargetIOS and (Target32Bit or Target64Bit))
+ Private Sub ReleaseNotesSocket_ContentReceived(sender As Kaju.HTTPSocketAsync, url As String, httpStatus As Integer, content As String)
+ #pragma unused sender
+ #pragma unused url
+
+ dim raw as string = content
+
+ if httpStatus = 404 or raw.Trim = "" then
+ //
+ // Do nothing
+ //
+
+ else
+ //
+ // Adjust the encoding
+ //
+
+ dim enc as TextEncoding
+
+ //
+ // See if the html contains a charset
+ //
+ static rxCharSetFinder as RegEx
+ if rxCharSetFinder is nil then
+ rxCharSetFinder = new RegEx
+ rxCharSetFinder.SearchPattern = " "" then
+ mReleaseNotesFromURL = raw
+ RaiseEvent ReleaseNotesReceived()
+ end if
+ end if
+
+ End Sub
+ #tag EndMethod
+
#tag Method, Flags = &h0
Sub RemoveBinary(binaryName As String)
if Binaries.HasKey( binaryName ) then
@@ -172,10 +266,33 @@ Inherits Kaju.Information
#tag EndMethod
+ #tag Hook, Flags = &h0
+ Event ImageReceived()
+ #tag EndHook
+
+ #tag Hook, Flags = &h0
+ Event ReleaseNotesReceived()
+ #tag EndHook
+
+
#tag Property, Flags = &h0
AppName As String
#tag EndProperty
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ if mReleaseNotesFromURL <> "" then
+ return mReleaseNotesFromURL
+ else
+ return mReleaseNotes
+ end if
+
+ End Get
+ #tag EndGetter
+ DisplayReleaseNotes As String
+ #tag EndComputedProperty
+
#tag ComputedProperty, Flags = &h0, CompatibilityFlags = (TargetHasGUI)
#tag Getter
Get
@@ -193,16 +310,14 @@ Inherits Kaju.Information
// Get the image
//
- dim http as new Kaju.HTTPSSocket
- url = http.GetRedirectAddress( url, 5 )
-
- dim data as string = http.Get( url, 5 )
-
- if data = "" then
- return nil
+ if ImageSocket is nil then
+ ImageSocket = new Kaju.HTTPSocketAsync
+ AddHandler ImageSocket.ContentReceived, WeakAddressOf ImageSocket_ContentReceived
end if
- mImage = Picture.FromData( data )
+ dim http as Kaju.HTTPSocketAsync = ImageSocket
+
+ http.Get( url, true )
Exception err as RuntimeException
mImage = nil
@@ -215,6 +330,14 @@ Inherits Kaju.Information
Image As Picture
#tag EndComputedProperty
+ #tag Property, Flags = &h0
+ ImageScale As Integer = 1
+ #tag EndProperty
+
+ #tag Property, Flags = &h21, CompatibilityFlags = (TargetWeb and (Target32Bit or Target64Bit)) or (TargetDesktop and (Target32Bit or Target64Bit)) or (TargetIOS and (Target32Bit or Target64Bit))
+ Private ImageSocket As Kaju.HTTPSocketAsync
+ #tag EndProperty
+
#tag Property, Flags = &h0
ImageURL As String
#tag EndProperty
@@ -231,6 +354,14 @@ Inherits Kaju.Information
MinimumRequiredVersion As String
#tag EndProperty
+ #tag Property, Flags = &h21
+ Private mReleaseNotes As String
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private mReleaseNotesFromURL As String
+ #tag EndProperty
+
#tag ComputedProperty, Flags = &h0
#tag Getter
Get
@@ -341,8 +472,93 @@ Inherits Kaju.Information
Private Shared PropInfoDictionary As Dictionary
#tag EndComputedProperty
- #tag Property, Flags = &h0
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ return mReleaseNotes
+
+ End Get
+ #tag EndGetter
+ #tag Setter
+ Set
+ mReleaseNotes = value
+
+ //
+ // The release notes might be straight HTML or them might be a URL.
+ // If the latter, the remainder will be alternate notes.
+ // This method will determine which it is and, if the latter, will
+ // attempt to fetch the notes. If it can't, it will return the alternate
+ // notes if any, or a message.
+ //
+ // The URL may start the first line followed by an EOL or may be in an
+ // HTML comment that starts the first line. The latter form will maintain
+ // better compatibility with previous versions of Kaju.
+ //
+ // Examples:
+ //
+ // http://something.com/UpdateInformation.json
+ //
+ //
+ //
+ //
+ //
+
+ mReleaseNotesFromURL = ""
+
+ static noInfoHTML as string = "" + KajuLocale.kNoUpdateInfoMessage + ""
+
+ static rxURLSplitter as RegEx
+ if rxURLSplitter is nil then
+ rxURLSplitter = new RegEx
+ rxURLSplitter.SearchPattern = _
+ "(?mi-Us)\A\x20*(?|(?:(http[^\s]+)\x20*\R)|(?:))([\s\S]*)"
+ end if
+
+ dim r as string = value
+
+ #if not TargetConsole then
+
+ dim matchURL as RegExMatch = rxURLSplitter.Search( value)
+ if matchURL isa RegExMatch then
+ dim url as string = matchURL.SubExpressionString( 1 ).Trim
+ dim alternateNotes as string = matchURL.SubExpressionString( 2 ).Trim
+
+ if ReleaseNotesSocket is nil then
+ ReleaseNotesSocket = new Kaju.HTTPSocketAsync
+ AddHandler ReleaseNotesSocket.ContentReceived, WeakAddressOf ReleaseNotesSocket_ContentReceived
+ end if
+
+ dim http as Kaju.HTTPSocketAsync = ReleaseNotesSocket
+ http.Get url, true
+ mReleaseNotes = alternateNotes
+ end if
+
+ #endif
+
+ if r.Trim = "" then
+ r = noInfoHTML
+ end if
+
+ mReleaseNotes = r
+
+ End Set
+ #tag EndSetter
ReleaseNotes As String
+ #tag EndComputedProperty
+
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ Return mReleaseNotesFromURL
+ End Get
+ #tag EndGetter
+ ReleaseNotesFromURL As String
+ #tag EndComputedProperty
+
+ #tag Property, Flags = &h21, CompatibilityFlags = (TargetWeb and (Target32Bit or Target64Bit)) or (TargetDesktop and (Target32Bit or Target64Bit)) or (TargetIOS and (Target32Bit or Target64Bit))
+ Private ReleaseNotesSocket As Kaju.HTTPSocketAsync
#tag EndProperty
#tag Property, Flags = &h0
@@ -426,18 +642,25 @@ Inherits Kaju.Information
#tag ViewBehavior
#tag ViewProperty
Name="AppName"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
#tag ViewProperty
Name="Image"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="Picture"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="ImageURL"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
@@ -447,11 +670,15 @@ Inherits Kaju.Information
Group="ID"
InitialValue="-2147483648"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="IsValid"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Left"
@@ -459,10 +686,13 @@ Inherits Kaju.Information
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="MinimumRequiredVersion"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
@@ -470,29 +700,33 @@ Inherits Kaju.Information
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
- #tag EndViewProperty
- #tag ViewProperty
- Name="ReleaseNotes"
- Group="Behavior"
- Type="String"
- EditorType="MultiLineEditor"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="RequiresPayment"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="StageCode"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Top"
@@ -500,23 +734,63 @@ Inherits Kaju.Information
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="UseTransparency"
+ Visible=false
Group="Behavior"
InitialValue="True"
Type="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Version"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
#tag ViewProperty
Name="VersionAsDouble"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="Double"
+ EditorType=""
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="ReleaseNotes"
+ Visible=false
+ Group="Behavior"
+ InitialValue=""
+ Type="String"
+ EditorType="MultiLineEditor"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="ImageScale"
+ Visible=false
+ Group="Behavior"
+ InitialValue="1"
+ Type="Integer"
+ EditorType=""
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="ReleaseNotesFromURL"
+ Visible=false
+ Group="Behavior"
+ InitialValue=""
+ Type="String"
+ EditorType="MultiLineEditor"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="DisplayReleaseNotes"
+ Visible=false
+ Group="Behavior"
+ InitialValue=""
+ Type="String"
+ EditorType="MultiLineEditor"
#tag EndViewProperty
#tag EndViewBehavior
End Class
diff --git a/Kaju Classes/Kaju/UpdateInitiater.xojo_code b/Kaju Classes/Kaju/UpdateInitiater.xojo_code
index f8728f0..3179a9a 100644
--- a/Kaju Classes/Kaju/UpdateInitiater.xojo_code
+++ b/Kaju Classes/Kaju/UpdateInitiater.xojo_code
@@ -366,14 +366,22 @@ Protected Class UpdateInitiater
dim scriptFile as FolderItem = tempFolder.Child( scriptName )
dim bs as BinaryStream = BinaryStream.Create( scriptFile, true )
bs.Write( script )
- if bs.LastErrorCode <> 0 then
- MsgBox "Error writing script file: " + str( bs.LastErrorCode )
- scriptFile = nil
- end if
+ #if XojoVersion < 2019.02
+ if bs.LastErrorCode <> 0 then
+ dim ex as new IOException
+ ex.ErrorNumber = bs.LastErrorCode
+ raise ex
+ end if
+ #endif
bs.Close
bs = nil
return scriptFile
+
+ exception err as IOException
+ MsgBox "Error writing script file: " + str( err.ErrorNumber )
+ return nil
+
End Function
#tag EndMethod
@@ -485,7 +493,7 @@ Protected Class UpdateInitiater
#tag Constant, Name = kUpdaterScript, Type = String, Dynamic = False, Default = \"", Scope = Private
#Tag Instance, Platform = Mac OS, Language = Default, Definition = \"#!/bin/bash\n\n#\n# FUNCTIONS\n#\n\nfunction log_cmd {\n /usr/bin/logger -t \"Kaju Update Script\" $@\n}\n\n# END FUNCTIONS\n\n#\n# These will be filled in by the calling app\n#\n\nAPP_NAME\x3D@@APP_NAME@@\nAPP_PARENT\x3D@@APP_PARENT@@\nAPP_VERSION\x3D@@APP_VERSION@@\nNEW_APP_NAME\x3D@@NEW_APP_NAME@@\nNEW_APP_PARENT\x3D@@NEW_APP_PARENT@@\nTEMP_FOLDER_PATH\x3D@@TEMP_FOLDER@@\nPID_FILE\x3D@@PID_FILE_PATH@@\n\n#\n# -----------------\n#\n\nreadonly true\x3D1\nreadonly false\x3D0\n\nAPP_PATH\x3D$APP_PARENT/$APP_NAME\nNEW_APP_PATH\x3D$NEW_APP_PARENT/$NEW_APP_NAME\n\nRENAMED_APP_NAME\x3D`echo \"$APP_NAME\" | /usr/bin/sed -E s/\\.[aA][pP]{2}//`-`date +%Y%m%d%H%M%S`.app\nRENAMED_APP_PATH\x3D$APP_PARENT/$RENAMED_APP_NAME\n\nlog_cmd \"STARTING UPDATE OF $APP_NAME\"\n\ncounter\x3D10\nwhile [ -f \"$PID_FILE\" ]\ndo\n log_cmd \"Checking to see if $PIDFILE exists\x2C $counter\"\n sleep 1\n \n let counter\x3Dcounter-1\n \n if [ $counter \x3D\x3D 0 ]\n then\n \tlog_cmd \'ERROR: Could not update app\x2C it never quit\'\n \texit 1\n fi\ndone\n\nPROCEED\x3D$true\n\n#\n# Rename the old application\n#\nlog_cmd \"Renaming old application $APP_NAME to $RENAMED_APP_NAME\"\nmv \"$APP_PATH\" \"$RENAMED_APP_PATH\"\n\n#\n# Make sure that succeeded\n#\nif [ $\? \x3D\x3D 0 ]\nthen\n log_cmd \'...confirmed\'\nelse\n log_cmd \"Could not rename old application to $RENAMED_APP_PATH\"\n PROCEED\x3D0\nfi\n\n#\n# Move in the replacement app\n#\nif [ $PROCEED \x3D\x3D $true ]\nthen\n log_cmd \"Moving new application $NEW_APP_PATH to folder $APP_PARENT\"\n mv \"$NEW_APP_PATH\" \"$APP_PARENT\"\n\n #\n # Make sure that worked\n #\n if [ $\? \x3D\x3D 0 ]\n then\n log_cmd \'...confirmed\'\n else\n log_cmd \"Could not move in new application\"\n log_cmd \"Attempting to restore old application and launch it\"\n mv \"$RENAMED_APP_PATH\" \"$APP_PATH\"\n open \"$APP_PATH\" --args --kaju-fail\n PROCEED\x3D$false\n fi\nfi\n\nif [ $PROCEED \x3D\x3D $true ]\nthen\n log_cmd \"Removing old application $RENAMED_APP_NAME\"\n rm -fr \"$RENAMED_APP_PATH\"\n \n APP_PATH\x3D$APP_PARENT/$NEW_APP_NAME\n log_cmd \"Starting new application at $APP_PATH\"\n \n open \"$APP_PATH\" --args --kaju-success \"$APP_VERSION\"\nfi\n\nif [ $PROCEED \x3D\x3D $true ]\nthen\n log_cmd \'Removing temp folder\'\n rm -fr \"$TEMP_FOLDER_PATH\"\nfi\n"
#Tag Instance, Platform = Linux, Language = Default, Definition = \"#!/bin/bash\n\n#\n# FUNCTIONS\n#\n\nfunction log_cmd {\n\t/usr/bin/logger -t \"Kaju Update Script\" $@\n}\n\n# END FUNCTIONS\n\n#\n# These will be filled in by the calling app\n#\n\nAPP_NAME\x3D@@APP_NAME@@\nAPP_PARENT\x3D@@APP_PARENT@@\nAPP_VERSION\x3D@@APP_VERSION@@\nNEW_APP_NAME\x3D@@NEW_APP_NAME@@\nNEW_APP_PARENT\x3D@@NEW_APP_PARENT@@\nTEMP_FOLDER_PATH\x3D@@TEMP_FOLDER@@\nPID_FILE\x3D@@PID_FILE_PATH@@\n\n#\n# This array will store the names of the items next to the executable\n# under the variable NEW_APP_OTHER_NAME\n#\nNEW_APP_OTHER_UB\x3D@@NEW_APP_OTHER_UB@@\n\n@@NEW_APP_OTHER_ARRAY@@\n\n#\n# -----------------\n#\n\nreadonly true\x3D1\nreadonly false\x3D0\n\nAPP_PATH\x3D$APP_PARENT/$APP_NAME\n\nBACKUP_PARENT\x3D$APP_PARENT/${APP_NAME}-`date +%Y%m%d%H%M%S`\nmkdir \"$BACKUP_PARENT\"\n\nlog_cmd \"STARTING UPDATE OF $APP_NAME\"\n\ncounter\x3D10\nwhile [ -f \"$PID_FILE\" ]\ndo\n\tlog_cmd \"Checking to see if $PIDFILE exists\x2C $counter\"\n\tsleep 1\n\t\n\tlet counter\x3Dcounter-1\n\t\n\tif [ $counter \x3D\x3D 0 ]\n\tthen\n\t\tlog_cmd \'ERROR: Could not update app\x2C it never quit\'\n\t\texit 1\n\tfi\ndone\n\nPROCEED\x3D$true\n\n#\n# Move the other items\n#\nlog_cmd \"Copying other items to backup $BACKUP_PARENT\"\n\ncounter\x3D0\nwhile [ $counter -le $NEW_APP_OTHER_UB ]\ndo\n\tthis_item\x3D${NEW_APP_OTHER_NAME[$counter]}\n\tlog_cmd \"Looking for item $this_item in $APP_PARENT\"\n\t\n\tthis_path\x3D$APP_PARENT/$this_item\n\tif [ -d \"$this_path\" ] || [ -f \"$this_path\" ]\n\tthen\n\t\tlog_cmd \"...found\x2C copying\"\n\t\tcp -pr \"$this_path\" \"$BACKUP_PARENT\"\n\t\tif [ $\? \x3D\x3D 0 ]\n\t\tthen\n\t\t\tlog_cmd \"...confirmed\"\n\t\telse\n\t\t\t log_cmd \"...FAILED!\"\n\t\t\t PROCEED\x3D$false\n\t\t\t break\n\t\tfi\n\tfi\n\t(( counter++ ))\ndone\n\n#\n# Move the executable\n#\nif [ $PROCEED \x3D\x3D $true ]\nthen\n\tlog_cmd \"Moving the executable $APP_NAME to backup\"\n\tmv \"$APP_PARENT/$APP_NAME\" \"$BACKUP_PARENT\"\n\tif [ $\? \x3D\x3D 0 ]\n\tthen\n\t\tlog_cmd \"...confirmed\"\n\telse\n\t\tlog_cmd \"...FAILED! (Error $\?)\"\n\t\tPROCEED\x3D$false\n\tfi\nfi\n\n#\n# Make sure there wasn\'t an error during the backup\n#\nif [ $PROCEED \x3D\x3D $true ]\nthen\n\tlog_cmd \'All items backed up\'\nelse\n\tlog_cmd \'Attempting to copy items back to parent\'\n\trsync -a --exclude\x3D\'.DS_Store\' \"${BACKUP_PARENT}/\" \"$APP_PARENT\"\nfi\n\n#\n# Move in the replacement files\n#\nif [ $PROCEED \x3D\x3D $true ]\nthen\n\tlog_cmd \"Copying files from $NEW_APP_PARENT to folder $APP_PARENT\"\n\trsync -a --exclude\x3D\'.DS_Store\' \"${NEW_APP_PARENT}/\" \"$APP_PARENT\"\n\t\n\tif [ $\? \x3D\x3D 0 ]\n\tthen\n\t\tlog_cmd \'...confirmed\'\n\telse\n\t\tlog_cmd \"...FAILED! (Error $\?)\"\n\t\tlog_cmd \"Attempting to restore old application\"\n\t\trsync -a --exclude\x3D\'.DS_Store\' \"${BACKUP_PARENT}/\" \"$APP_PARENT\"\n\t\tPROCEED\x3D$false\n\t\tbreak\n\tfi\nfi\n\n#\n# Removed the backup folder if everything has gone swimmingly so\n#\nif [ $PROCEED \x3D\x3D $true ]\nthen\n\tlog_cmd \'Removing backup\'\n\trm -r \"$BACKUP_PARENT\"\nfi\n\n#\n# Launch the application\n#\nif [ $PROCEED \x3D $true ]\nthen\n\tlog_cmd \'Making the new app executable\'\n\tchmod +x \"$APP_PARENT/$NEW_APP_NAME\"\n\tlog_cmd \'Launching new app\'\n\t\"$APP_PARENT/$NEW_APP_NAME\" --kaju-success \"$APP_VERSION\"\nelse\n\tlog_cmd \'Launching old app\'\n\t\"$APP_PARENT/$APP_NAME\" --kaju-fail\nfi\n\nlog_cmd \'Removing temp folder\'\nrm -fr \"$TEMP_FOLDER_PATH\"\n"
- #Tag Instance, Platform = Windows, Language = Default, Definition = \"@ECHO OFF \n\nREM\nREM These will be filled in by the calling app\nREM\n\nSET APP_NAME\x3D@@APP_NAME@@\nSET APP_PARENT\x3D@@APP_PARENT@@\nSET APP_VERSION\x3D@@APP_VERSION@@\nSET NEW_APP_NAME\x3D@@NEW_APP_NAME@@\nSET NEW_APP_PARENT\x3D@@NEW_APP_PARENT@@\nSET TEMP_FOLDER_PATH\x3D@@TEMP_FOLDER@@\nSET DECOMPRESSED_FOLDER_PATH\x3D@@DECOMPRESSED_FOLDER@@\nSET PID_FILE\x3D@@PID_FILE_PATH@@\n\nREM\nREM -----------------\nREM\n\nSET TODAY_DATE\x3D%DATE:~10\x2C4%-%DATE:~4\x2C2%-%DATE:~7\x2C2% %TIME:~0\x2C2%:%TIME:~3\x2C2%:%TIME:~6\x2C2%\nSET APP_PATH\x3D%APP_PARENT%\\%APP_NAME%\n\nSET BACKUP_PARENT\x3D%APP_PATH%-%DATE:~10\x2C4%%DATE:~4\x2C2%%DATE:~7\x2C2%%TIME:~0\x2C2%%TIME:~3\x2C2%%TIME:~6\x2C2%\n\nSET LOGGER\x3D%APP_PARENT%\\%NEW_APP_NAME% Update Log.txt\nECHO \"STARTED ON %TODAY_DATE%\" >> \"%LOGGER%\" 2>&1\n\nFOR /L %%i IN (1\x2C1\x2C10) DO (\n\tIF NOT EXIST \"%PID_FILE%\" (\n\t\tGOTO :program_exited\n\t)\n\n\tREM Windows version of sleep 1. Starting in Windows Vista\x2C the sleep command was removed.\n\tping -n 2 127.0.0.1 >nul\n\n\tIF %%i \x3D\x3D 10 (\n\t\tECHO ERROR: Could not update app\x2C it never quit >> \"%LOGGER%\" 2>&1\n\t\tEXIT /B 1\n\t)\n)\n:program_exited\n\nmkdir \"%BACKUP_PARENT%\"\n\nSET PROCEED\x3D1\n\nREM\nREM Move the other items\nREM\nECHO \"Copying items to backup %BACKUP_PARENT%\" >> \"%LOGGER%\" 2>&1\n\nREM We will need to manually populate these move commands. Windows Batch doesn\'t really handle arrays\x2C\nREM only looping through space delimited elements of a string. Below is a template for moving one such file.\n\nREM BEGIN PSEUDO-ARRAY\nSET THIS_ITEM\x3D@@OTHER_NAME@@\nSET THIS_PATH\x3D%APP_PARENT%\\%THIS_ITEM%\nECHO \"Looking for item %THIS_PATH%\" >> \"%LOGGER%\" 2>&1\nIF EXIST \"%THIS_PATH%\" (\n\tGOTO :copy_@@OTHER_NAME_WO_SPACES@@\n)\nECHO \"...not found as file\x2C trying as directory\" >> \"%LOGGER%\" 2>&1\nIF EXIST \"%THIS_PATH%\\NUL\" (\n\tGOTO :copy_@@OTHER_NAME_WO_SPACES@@\n) ELSE (\n\tECHO \"...NOT FOUND!\" >> \"%LOGGER%\" 2>&1\n\tGOTO :finished_with_@@OTHER_NAME_WO_SPACES@@\n)\n\n:copy_@@OTHER_NAME_WO_SPACES@@\n\nECHO \"...found\x2C copying\" >> \"%LOGGER%\" 2>&1\nCOPY \"%THIS_PATH%\" \"%BACKUP_PARENT%\" >> \"%LOGGER%\" 2>&1\nIF %ERRORLEVEL% NEQ 0 (\n\tECHO \"...FAILED! (Error %ERRORLEVEL%)\" >> \"%LOGGER%\" 2>&1\n\tSET PROCEED\x3D0\n\tGOTO :restore_from_backup\n) ELSE (\n\tECHO \"...confirmed\" >> \"%LOGGER%\" 2>&1\n)\n\n:finished_with_@@OTHER_NAME_WO_SPACES@@\n\nREM END PSEUDO-ARRAY\n\nREM\nREM Move the executable to backup\nREM\nIF %PROCEED% \x3D\x3D 1 (\n\tECHO \"Moving the executable %APP_NAME% to backup\" >> \"%LOGGER%\" 2>&1\n\tMOVE \"%APP_PATH%\" \"%BACKUP_PARENT%\" >> \"%LOGGER%\" 2>&1\n\tIF %ERRORLEVEL% NEQ 0 (\n\t\tECHO \"...FAILED! (Error %ERRORLEVEL%)\" >> \"%LOGGER%\" 2>&1\n\t\tSET PROCEED\x3D0\n\t\tGOTO :restore_from_backup\n\t) ELSE (\n\t\tECHO \"...confirmed\" >> \"%LOGGER%\" 2>&1\n\t)\n)\n\nREM\nREM Make sure there wasn\'t an error during the move\nREM\nIF %PROCEED% \x3D\x3D 1 (\n\tECHO \"All items moved to backup\" >> \"%LOGGER%\" 2>&1\n)\n\nREM\nREM Copy in the replacement files\nREM\n\nIF %PROCEED% \x3D\x3D 1 (\n\tECHO \"Copying files from %NEW_APP_PARENT% to folder %APP_PARENT%\" >> \"%LOGGER%\" 2>&1\n\tXCOPY /g /y /e /k \"%NEW_APP_PARENT%\" \"%APP_PARENT%\" >> \"%LOGGER%\" 2>&1\n\tIF %ERRORLEVEL% NEQ 0 (\n\t\tECHO \"...FAILED! (Error %ERRORLEVEL%)\" >> \"%LOGGER%\" 2>&1\n\t\tSET PROCEED\x3D0\n\t\tGOTO :restore_from_backup\n\t) ELSE (\n\t\tECHO \"...confirmed\" >> \"%LOGGER%\" 2>&1\n\t)\n)\n\nREM\nREM If we get here\x2C it all worked\nREM\nIF %PROCEED% \x3D\x3D 1 (\n\tGOTO :all_succeeded\n)\n\n:restore_from_backup\nIF %PROCEED% \x3D\x3D 0 (\n\tECHO \"Attempting to restore old application\" >> \"%LOGGER%\" 2>&1\n\n\tXCOPY /g /y /e /k \"%BACKUP_PARENT%\" \"%APP_PARENT%\" >> \"%LOGGER%\" 2>&1\n\tIF %ERRORLEVEL% EQU 0 (\n\t\tRMDIR /S /Q \"%BACKUP_PARENT%\" >> \"%LOGGER%\" 2>&1\n\t)\n)\nGOTO :launch_application\n\n:all_succeeded\nREM\nREM Remove the backup and decompressed folders if everything has gone swimmingly so far\nREM\nIF %PROCEED% \x3D\x3D 1 (\n\tECHO \"Removing backup\" >> \"%LOGGER%\" 2>&1\n\tRMDIR /S /Q \"%BACKUP_PARENT%\" >> \"%LOGGER%\" 2>&1\n\tECHO \"Removing decompressed folder\" >> \"%LOGGER%\" 2>&1\n\tRMDIR /S /Q \"%DECOMPRESSED_FOLDER_PATH%\" >> \"%LOGGER%\" 2>&1\n)\n\nREM\nREM Launch the application\nREM\n:launch_application\nIF %PROCEED% \x3D\x3D 1 (\n\tECHO \"Launching new app\" >> \"%LOGGER%\" 2>&1\n\tSTART \"\" \"%APP_PARENT%\\%NEW_APP_NAME%\" --kaju-success %APP_VERSION%\n\tGOTO :remove_backup_folder\n) ELSE (\n\tECHO \"Launching old app\" >> \"%LOGGER%\" 2>&1\n\tSTART \"\" \"%APP_PATH%\" --kaju-fail\n)\n\n:remove_backup_folder\nECHO \"Removing temp folder\" >> \"%LOGGER%\" 2>&1\nRMDIR /S /Q \"%TEMP_FOLDER_PATH%\" >> \"%LOGGER%\" 2>&1\n"
+ #Tag Instance, Platform = Windows, Language = Default, Definition = \"@ECHO OFF \n\nREM\nREM These will be filled in by the calling app\nREM\n\nSET APP_NAME\x3D@@APP_NAME@@\nSET APP_PARENT\x3D@@APP_PARENT@@\nSET APP_VERSION\x3D@@APP_VERSION@@\nSET NEW_APP_NAME\x3D@@NEW_APP_NAME@@\nSET NEW_APP_PARENT\x3D@@NEW_APP_PARENT@@\nSET TEMP_FOLDER_PATH\x3D@@TEMP_FOLDER@@\nSET DECOMPRESSED_FOLDER_PATH\x3D@@DECOMPRESSED_FOLDER@@\nSET PID_FILE\x3D@@PID_FILE_PATH@@\n\nREM\nREM -----------------\nREM\n\nSET TODAY_DATE\x3D%DATE:~10\x2C4%-%DATE:~4\x2C2%-%DATE:~7\x2C2% %TIME:~0\x2C2%:%TIME:~3\x2C2%:%TIME:~6\x2C2%\nSET APP_PATH\x3D%APP_PARENT%\\%APP_NAME%\n\nSET BACKUP_PARENT\x3D%APP_PATH%-%DATE:~10\x2C4%%DATE:~4\x2C2%%DATE:~7\x2C2%%TIME:~0\x2C2%%TIME:~3\x2C2%%TIME:~6\x2C2%\n\nSET LOGGER\x3D%APP_PARENT%\\%NEW_APP_NAME% Update Log.txt\nECHO \"STARTED ON %TODAY_DATE%\" >> \"%LOGGER%\" 2>&1\n\nFOR /L %%i IN (1\x2C1\x2C10) DO (\n\tIF NOT EXIST \"%PID_FILE%\" (\n\t\tGOTO :program_exited\n\t)\n\n\tREM Windows version of sleep 1. Starting in Windows Vista\x2C the sleep command was removed.\n\tping -n 2 127.0.0.1 >nul\n\n\tIF %%i \x3D\x3D 10 (\n\t\tECHO ERROR: Could not update app\x2C it never quit >> \"%LOGGER%\" 2>&1\n\t\tEXIT /B 1\n\t)\n)\n:program_exited\n\nmkdir \"%BACKUP_PARENT%\"\n\nSET PROCEED\x3D1\n\nREM\nREM Move the other items\nREM\nECHO \"Copying items to backup %BACKUP_PARENT%\" >> \"%LOGGER%\" 2>&1\n\nREM We will need to manually populate these move commands. Windows Batch doesn\'t really handle arrays\x2C\nREM only looping through space delimited elements of a string. Below is a template for moving one such file.\n\nREM BEGIN PSEUDO-ARRAY\nSET THIS_ITEM\x3D@@OTHER_NAME@@\nSET THIS_PATH\x3D%APP_PARENT%\\%THIS_ITEM%\nECHO \"Looking for item %THIS_PATH%\" >> \"%LOGGER%\" 2>&1\nIF EXIST \"%THIS_PATH%\" (\n\tGOTO :copy_@@OTHER_NAME_WO_SPACES@@\n)\nECHO \"...not found as file\x2C trying as directory\" >> \"%LOGGER%\" 2>&1\nIF EXIST \"%THIS_PATH%\\NUL\" (\n\tGOTO :copy_@@OTHER_NAME_WO_SPACES@@\n) ELSE (\n\tECHO \"...NOT FOUND!\" >> \"%LOGGER%\" 2>&1\n\tGOTO :finished_with_@@OTHER_NAME_WO_SPACES@@\n)\n\n:copy_@@OTHER_NAME_WO_SPACES@@\n\nECHO \"...found\x2C copying\" >> \"%LOGGER%\" 2>&1\nCOPY \"%THIS_PATH%\" \"%BACKUP_PARENT%\" >> \"%LOGGER%\" 2>&1\nIF %ERRORLEVEL% NEQ 0 (\n\tECHO \"...FAILED! (Error %ERRORLEVEL%)\" >> \"%LOGGER%\" 2>&1\n\tSET PROCEED\x3D0\n\tGOTO :restore_from_backup\n) ELSE (\n\tECHO \"...confirmed\" >> \"%LOGGER%\" 2>&1\n)\n\n:finished_with_@@OTHER_NAME_WO_SPACES@@\n\nREM END PSEUDO-ARRAY\n\nREM\nREM Move the executable to backup\nREM\nIF %PROCEED% \x3D\x3D 1 (\n\tECHO \"Moving the executable %APP_NAME% to backup\" >> \"%LOGGER%\" 2>&1\n\tMOVE \"%APP_PATH%\" \"%BACKUP_PARENT%\" >> \"%LOGGER%\" 2>&1\n\tIF %ERRORLEVEL% NEQ 0 (\n\t\tECHO \"...FAILED! (Error %ERRORLEVEL%)\" >> \"%LOGGER%\" 2>&1\n\t\tSET PROCEED\x3D0\n\t\tGOTO :restore_from_backup\n\t) ELSE (\n\t\tECHO \"...confirmed\" >> \"%LOGGER%\" 2>&1\n\t)\n)\n\nREM\nREM Make sure there wasn\'t an error during the move\nREM\nIF %PROCEED% \x3D\x3D 1 (\n\tECHO \"All items moved to backup\" >> \"%LOGGER%\" 2>&1\n)\n\nREM\nREM Copy in the replacement files\nREM\n\nIF %PROCEED% \x3D\x3D 1 (\n\tECHO \"Copying files from %NEW_APP_PARENT% to folder %APP_PARENT%\" >> \"%LOGGER%\" 2>&1\n\tXCOPY /g /y /e /k \"%NEW_APP_PARENT%\" \"%APP_PARENT%\" >> \"%LOGGER%\" 2>&1\n\tIF %ERRORLEVEL% NEQ 0 (\n\t\tECHO \"...FAILED! (Error %ERRORLEVEL%)\" >> \"%LOGGER%\" 2>&1\n\t\tSET PROCEED\x3D0\n\t\tGOTO :restore_from_backup\n\t) ELSE (\n\t\tECHO \"...confirmed\" >> \"%LOGGER%\" 2>&1\n\t)\n)\n\nREM\nREM If we get here\x2C it all worked\nREM\nIF %PROCEED% \x3D\x3D 1 (\n\tGOTO :all_succeeded\n)\n\n:restore_from_backup\nIF %PROCEED% \x3D\x3D 0 (\n\tECHO \"Attempting to restore old application\" >> \"%LOGGER%\" 2>&1\n\n\tXCOPY /g /y /e /k \"%BACKUP_PARENT%\" \"%APP_PARENT%\" >> \"%LOGGER%\" 2>&1\n\tIF %ERRORLEVEL% EQU 0 (\n\t\tRMDIR /S /Q \"%BACKUP_PARENT%\" >> \"%LOGGER%\" 2>&1\n\t)\n)\nGOTO :launch_application\n\n:all_succeeded\nREM\nREM Remove the backup and decompressed folders if everything has gone swimmingly so far\nREM\nIF %PROCEED% \x3D\x3D 1 (\n\tECHO \"Removing backup...\" >> \"%LOGGER%\" 2>&1\n\tRMDIR /S /Q \"%BACKUP_PARENT%\" >> \"%LOGGER%\" 2>&1\n\tECHO \"... removed\" >> \"%LOGGER%\" 2>&1\n\tECHO \"Removing decompressed folder...\" >> \"%LOGGER%\" 2>&1\n\tRMDIR /S /Q \"%DECOMPRESSED_FOLDER_PATH%\" >> \"%LOGGER%\" 2>&1\n\tECHO \"... removed\" >> \"%LOGGER%\" 2>&1\n\tGOTO :launch_application\n)\n\nREM\nREM Launch the application\nREM\n:launch_application\nECHO \"Launching application...\" >> \"%LOGGER%\" 2>&1\nIF %PROCEED% \x3D\x3D 1 (\n\tECHO \"... new app\" >> \"%LOGGER%\" 2>&1\n\tSTART \"\" \"%APP_PARENT%\\%NEW_APP_NAME%\" --kaju-success \"%APP_VERSION%\"\n\tGOTO :remove_backup_folder\n) ELSE (\n\tECHO \"... OLD app\" >> \"%LOGGER%\" 2>&1\n\tSTART \"\" \"%APP_PATH%\" --kaju-fail\n)\n\n:remove_backup_folder\nECHO \"Removing temp folder...\" >> \"%LOGGER%\" 2>&1\nRMDIR /S /Q \"%TEMP_FOLDER_PATH%\" >> \"%LOGGER%\" 2>&1 && ( ECHO \"... removed\" >> \"%LOGGER%\" 2>&1 && ( ECHO \"DONE\" >> \"%LOGGER%\" 2>&1 ) ) || ( ECHO \"... FAILED!\" >> \"%LOGGER%\" 2>&1 )\n"
#tag EndConstant
@@ -496,6 +504,7 @@ Protected Class UpdateInitiater
Group="ID"
InitialValue="-2147483648"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Left"
@@ -503,16 +512,21 @@ Protected Class UpdateInitiater
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="ReplacementExecutableName"
+ Visible=false
Group="Behavior"
+ InitialValue=""
Type="String"
EditorType="MultiLineEditor"
#tag EndViewProperty
@@ -520,7 +534,9 @@ Protected Class UpdateInitiater
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Top"
@@ -528,6 +544,7 @@ Protected Class UpdateInitiater
Group="Position"
InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag EndViewBehavior
End Class
diff --git a/Kaju Classes/Kaju/ZipShell.xojo_code b/Kaju Classes/Kaju/ZipShell.xojo_code
index 965be52..7fec7a3 100644
--- a/Kaju Classes/Kaju/ZipShell.xojo_code
+++ b/Kaju Classes/Kaju/ZipShell.xojo_code
@@ -256,21 +256,72 @@ Inherits Shell
#tag ViewBehavior
+ #tag ViewProperty
+ Name="ExecuteMode"
+ Visible=true
+ Group=""
+ InitialValue=""
+ Type="ExecuteModes"
+ EditorType="Enum"
+ #tag EnumValues
+ "0 - Synchronous"
+ "1 - Asynchronous"
+ "2 - Interactive"
+ #tag EndEnumValues
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="ExitCode"
+ Visible=false
+ Group="Behavior"
+ InitialValue=""
+ Type="Integer"
+ EditorType=""
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Result"
+ Visible=false
+ Group="Behavior"
+ InitialValue=""
+ Type="String"
+ EditorType=""
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="PID"
+ Visible=false
+ Group="Behavior"
+ InitialValue=""
+ Type="Integer"
+ EditorType=""
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="IsRunning"
+ Visible=false
+ Group="Behavior"
+ InitialValue=""
+ Type="Boolean"
+ EditorType=""
+ #tag EndViewProperty
#tag ViewProperty
Name="Arguments"
Visible=true
+ Group=""
+ InitialValue=""
Type="String"
EditorType="String"
#tag EndViewProperty
#tag ViewProperty
Name="Backend"
Visible=true
+ Group=""
+ InitialValue=""
Type="String"
EditorType="String"
#tag EndViewProperty
#tag ViewProperty
Name="Canonical"
Visible=true
+ Group=""
+ InitialValue=""
Type="Boolean"
EditorType="Boolean"
#tag EndViewProperty
@@ -278,35 +329,39 @@ Inherits Shell
Name="Index"
Visible=true
Group="ID"
+ InitialValue=""
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Left"
Visible=true
Group="Position"
+ InitialValue=""
Type="Integer"
- #tag EndViewProperty
- #tag ViewProperty
- Name="Mode"
- Visible=true
- Type="Integer"
- EditorType="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="TimeOut"
Visible=true
+ Group=""
+ InitialValue=""
Type="Integer"
EditorType="Integer"
#tag EndViewProperty
@@ -314,7 +369,9 @@ Inherits Shell
Name="Top"
Visible=true
Group="Position"
+ InitialValue=""
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag EndViewBehavior
End Class
diff --git a/Kaju Classes/KajuUpdateWindow.xojo_window b/Kaju Classes/KajuUpdateWindow.xojo_window
index 384405f..24e855e 100644
--- a/Kaju Classes/KajuUpdateWindow.xojo_window
+++ b/Kaju Classes/KajuUpdateWindow.xojo_window
@@ -3,7 +3,6 @@ Begin Window KajuUpdateWindow
BackColor = &cFFFFFF00
Backdrop = 0
CloseButton = False
- Compatibility = ""
Composite = True
Frame = 0
FullScreen = False
@@ -11,7 +10,7 @@ Begin Window KajuUpdateWindow
HasBackColor = False
Height = 600
ImplicitInstance= True
- LiveResize = False
+ LiveResize = "False"
MacProcID = 0
MaxHeight = 32000
MaximizeButton = False
@@ -26,31 +25,10 @@ Begin Window KajuUpdateWindow
Title = "#KajuLocale.kWindowTitle"
Visible = True
Width = 800
- Begin HTMLViewer hvNotes
- AutoDeactivate = True
- Enabled = True
- Height = 445
- HelpTag = ""
- Index = -2147483648
- Left = 149
- LockBottom = False
- LockedInPosition= False
- LockLeft = True
- LockRight = False
- LockTop = True
- Renderer = 1
- Scope = 2
- TabIndex = 1
- TabPanelIndex = 0
- TabStop = True
- Top = 84
- Visible = True
- Width = 631
- End
Begin PushButton btnOK
AutoDeactivate = True
Bold = False
- ButtonStyle = "0"
+ ButtonStyle = 0
Cancel = False
Caption = "#KajuLocale.kInstallButton"
Default = True
@@ -62,7 +40,7 @@ Begin Window KajuUpdateWindow
Italic = False
Left = 630
LockBottom = False
- LockedInPosition= False
+ LockedInPosition= True
LockLeft = True
LockRight = False
LockTop = True
@@ -74,6 +52,7 @@ Begin Window KajuUpdateWindow
TextSize = 0.0
TextUnit = 0
Top = 555
+ Transparent = False
Underline = False
Visible = True
Width = 150
@@ -81,7 +60,7 @@ Begin Window KajuUpdateWindow
Begin PushButton btnCancel
AutoDeactivate = True
Bold = False
- ButtonStyle = "0"
+ ButtonStyle = 0
Cancel = True
Caption = "#KajuLocale.kRemindMeLaterButton"
Default = False
@@ -93,7 +72,7 @@ Begin Window KajuUpdateWindow
Italic = False
Left = 468
LockBottom = False
- LockedInPosition= False
+ LockedInPosition= True
LockLeft = True
LockRight = False
LockTop = True
@@ -105,6 +84,7 @@ Begin Window KajuUpdateWindow
TextSize = 0.0
TextUnit = 0
Top = 555
+ Transparent = False
Underline = False
Visible = True
Width = 150
@@ -112,7 +92,7 @@ Begin Window KajuUpdateWindow
Begin PushButton btnSkipVersion
AutoDeactivate = True
Bold = False
- ButtonStyle = "0"
+ ButtonStyle = 0
Cancel = False
Caption = "#KajuLocale.kSkipVersionButton"
Default = False
@@ -124,7 +104,7 @@ Begin Window KajuUpdateWindow
Italic = False
Left = 149
LockBottom = False
- LockedInPosition= False
+ LockedInPosition= True
LockLeft = True
LockRight = False
LockTop = True
@@ -136,6 +116,7 @@ Begin Window KajuUpdateWindow
TextSize = 0.0
TextUnit = 0
Top = 555
+ Transparent = False
Underline = False
Visible = True
Width = 150
@@ -153,7 +134,7 @@ Begin Window KajuUpdateWindow
Italic = False
Left = 149
LockBottom = False
- LockedInPosition= False
+ LockedInPosition= True
LockLeft = True
LockRight = False
LockTop = True
@@ -188,7 +169,7 @@ Begin Window KajuUpdateWindow
Italic = False
Left = 149
LockBottom = False
- LockedInPosition= False
+ LockedInPosition= True
LockLeft = True
LockRight = False
LockTop = True
@@ -223,7 +204,7 @@ Begin Window KajuUpdateWindow
Italic = False
Left = 149
LockBottom = False
- LockedInPosition= False
+ LockedInPosition= True
LockLeft = True
LockRight = False
LockTop = True
@@ -258,7 +239,7 @@ Begin Window KajuUpdateWindow
Italic = False
Left = 149
LockBottom = False
- LockedInPosition= False
+ LockedInPosition= True
LockLeft = True
LockRight = False
LockTop = True
@@ -285,47 +266,37 @@ Begin Window KajuUpdateWindow
Enabled = True
Height = 20
HelpTag = ""
+ Indeterminate = False
Index = -2147483648
InitialParent = ""
Left = 20
LockBottom = False
- LockedInPosition= False
+ LockedInPosition= True
LockLeft = True
LockRight = False
LockTop = True
- Maximum = 0
+ Maximum = 100
Scope = 2
TabIndex = 8
TabPanelIndex = 0
- TabStop = True
Top = 555
- Value = 0
+ Transparent = False
+ Value = 0.0
Visible = False
Width = 117
End
- Begin Kaju.HTTPSSocket hsSocket
- CertificateFile =
- CertificatePassword= ""
- CertificateRejectionFile=
- ConnectionType = 2
- Enabled = True
- ForceSecure = False
- Index = -2147483648
- InitialParent = ""
- LockedInPosition= False
- Scope = 2
- Secure = False
- TabPanelIndex = 0
- End
Begin Kaju.ZipShell shZipper
Arguments = ""
Backend = ""
Canonical = False
- Enabled = True
+ ErrorCode = 0
Index = -2147483648
InitialParent = ""
+ IsRunning = False
LockedInPosition= False
Mode = 1
+ PID = 0
+ Result = ""
Scope = 2
TabPanelIndex = 0
TimeOut = 0
@@ -338,11 +309,11 @@ Begin Window KajuUpdateWindow
Index = -2147483648
Left = -345
LockBottom = False
- LockedInPosition= False
+ LockedInPosition= True
LockLeft = True
LockRight = False
LockTop = True
- Renderer = 0
+ Renderer = 1
Scope = 2
TabIndex = 9
TabPanelIndex = 0
@@ -364,7 +335,7 @@ Begin Window KajuUpdateWindow
Italic = False
Left = 20
LockBottom = False
- LockedInPosition= False
+ LockedInPosition= True
LockLeft = True
LockRight = False
LockTop = True
@@ -396,16 +367,16 @@ Begin Window KajuUpdateWindow
HelpTag = ""
Index = -2147483648
InitialParent = ""
- InitialValue = ""
+ InitialValue = "updates"
Italic = False
Left = 36
ListIndex = 0
LockBottom = False
- LockedInPosition= False
+ LockedInPosition= True
LockLeft = True
LockRight = False
LockTop = True
- Scope = 0
+ Scope = 2
TabIndex = 11
TabPanelIndex = 0
TabStop = True
@@ -413,19 +384,48 @@ Begin Window KajuUpdateWindow
TextSize = 0.0
TextUnit = 0
Top = 87
+ Transparent = False
Underline = False
Visible = True
Width = 101
End
Begin Timer tmrTimeout
- Enabled = True
Index = -2147483648
InitialParent = ""
LockedInPosition= False
Mode = 0
Period = 5000
- Scope = 0
+ Scope = 2
+ TabPanelIndex = 0
+ End
+ Begin Kaju.HTTPSocketAsync hsSocket
+ AllowCertificateValidation= False
+ HTTPStatusCode = 0
+ Index = -2147483648
+ LockedInPosition= False
+ Scope = 2
+ TabPanelIndex = 0
+ End
+ Begin HTMLViewer hvNotes
+ AutoDeactivate = True
+ Enabled = True
+ Height = 445
+ HelpTag = ""
+ Index = -2147483648
+ Left = 149
+ LockBottom = False
+ LockedInPosition= True
+ LockLeft = True
+ LockRight = False
+ LockTop = True
+ Renderer = 1
+ Scope = 2
+ TabIndex = 1
TabPanelIndex = 0
+ TabStop = True
+ Top = 84
+ Visible = True
+ Width = 631
End
End
#tag EndWindow
@@ -443,14 +443,13 @@ End
Kaju.DeleteRecursive( f )
next
+ CurrentUpdate = nil
+
End Sub
#tag EndEvent
#tag Event
Sub Open()
- RelativeToFolderItem = GetTemporaryFolderItem
- DeleteOnClose.Append RelativeToFolderItem
-
#if not TargetMacOS then
//
// Switch the buttons around for other platforms
@@ -518,9 +517,7 @@ End
end if
Kaju.CancelUpdate
- if hsSocket.IsConnected then
- hsSocket.Disconnect
- end if
+ hsSocket.Disconnect
if shZipper.IsRunning then
shZipper.Close
@@ -536,6 +533,30 @@ End
End Sub
#tag EndMethod
+ #tag Method, Flags = &h21
+ Private Sub ChangeBackgroudImage(update As Kaju.UpdateInformation)
+ dim useTransparency as boolean = update.UseTransparency
+ dim p as Picture = update.Image
+ if p is nil then
+ p = Checker.DefaultImage
+ useTransparency = Checker.DefaultUseTransparency
+ end if
+
+ if p <> nil and useTransparency then
+ dim faded as new Picture( p.Width, p.Height )
+
+ const kTransparencyPercent = 50.0
+ faded.Graphics.Transparency = kTransparencyPercent
+
+ faded.Graphics.DrawPicture( p, 0, 0 )
+
+ p = faded
+ end if
+
+ self.BackgroundImage = p
+ End Sub
+ #tag EndMethod
+
#tag Method, Flags = &h0
Sub ChooseUpdate(checker As Kaju.UpdateChecker, updates() As Kaju.UpdateInformation)
self.Checker = checker
@@ -565,6 +586,11 @@ End
// Set up the menu with the available updates.
// It will set up the rest of the controls.
//
+ // NOTE: Linux requires there to be an initial value in
+ // the pop-up menu or the Window won't draw
+ // correctly.
+ //
+ pumUpdates.DeleteAllRows
for i as integer = 0 to Updates.Ubound
dim update as Kaju.UpdateInformation = updates( i )
@@ -586,6 +612,24 @@ End
End Sub
#tag EndMethod
+ #tag Method, Flags = &h21
+ Private Sub CurrentUpdate_ImageReceived(sender As Kaju.UpdateInformation)
+ if sender is CurrentUpdate then
+ ChangeBackgroudImage( CurrentUpdate )
+ end if
+
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h21
+ Private Sub CurrentUpdate_ReleaseNotesReceived(sender As Kaju.UpdateInformation)
+ if sender is CurrentUpdate then
+ DisplayVersionInfo( CurrentUpdate )
+ end if
+
+ End Sub
+ #tag EndMethod
+
#tag Method, Flags = &h21
Private Sub DisplayVersionInfo(update As Kaju.UpdateInformation)
//
@@ -612,49 +656,13 @@ End
//
// Get the background picture, if any
//
- dim useTransparency as boolean = update.UseTransparency
- dim p as Picture = update.Image
- if p is nil then
- p = Checker.DefaultImage
- useTransparency = Checker.DefaultUseTransparency
- end if
-
- if p <> nil and useTransparency then
- dim faded as new Picture( p.Width, p.Height, 32 )
- faded.Transparent = Picture.TransparentWhite
-
- const kTransparencyPercent = 50.0
- #if TargetWindows then
- if App.UseGDIPlus then
- #endif
- faded.Graphics.Transparency = kTransparencyPercent
- #if TargetWindows then
- end if
- #endif
-
- faded.Graphics.DrawPicture( p, 0, 0 )
-
- #if TargetWindows then
- if App.UseGDIPlus then
- #endif
- dim mask as new Picture( p.Width, p.Height )
- mask.Graphics.DrawPicture( p.Mask, 0, 0 )
- faded.Mask = mask
- #if TargetWindows then
- end if
- #endif
-
- p = faded
- end if
-
- self.BackgroundImage = p
+ ChangeBackgroudImage update
//
// Show the release notes
//
- dim source as string = update.ReleaseNotes
- source = Kaju.ProcessReleaseNotes( source )
- hvNotes.LoadPage( source, RelativeToFolderItem )
+ dim source as string = update.DisplayReleaseNotes
+ hvNotes.LoadPage( source, nil )
//
// hvNotes.CancelLoad will set self.Loading back to false
@@ -717,15 +725,10 @@ End
dim url as string = SelectedBinary.URL
- //
- // Check for redirection
- //
- url = hsSocket.GetRedirectAddress( url, 5 )
-
//
// Start the download
//
- hsSocket.Get( url, DownloadFile )
+ hsSocket.Get( url, DownloadFile, true )
//
// Start the timeout timer
@@ -927,6 +930,31 @@ End
Private CurrentStage As Stage
#tag EndProperty
+ #tag ComputedProperty, Flags = &h21
+ #tag Getter
+ Get
+ return mCurrentUpdate
+ End Get
+ #tag EndGetter
+ #tag Setter
+ Set
+ dim current as Kaju.UpdateInformation = mCurrentUpdate
+ if current isa object then
+ RemoveHandler current.ImageReceived, WeakAddressOf CurrentUpdate_ImageReceived
+ RemoveHandler current.ReleaseNotesReceived, WeakAddressOf CurrentUpdate_ReleaseNotesReceived
+ end if
+
+ mCurrentUpdate = value
+ if value isa object then
+ AddHandler value.ImageReceived, WeakAddressOf CurrentUpdate_ImageReceived
+ AddHandler value.ReleaseNotesReceived, WeakAddressOf CurrentUpdate_ReleaseNotesReceived
+ end if
+
+ End Set
+ #tag EndSetter
+ Private CurrentUpdate As Kaju.UpdateInformation
+ #tag EndComputedProperty
+
#tag Property, Flags = &h21
#tag Note
Files/folders that shoudl be deleted if the user cancelled
@@ -962,7 +990,7 @@ End
#tag EndProperty
#tag Property, Flags = &h21
- Private RelativeToFolderItem As FolderItem
+ Attributes( hidden ) Private mCurrentUpdate As Kaju.UpdateInformation
#tag EndProperty
#tag Property, Flags = &h21
@@ -985,30 +1013,6 @@ End
#tag EndWindowCode
-#tag Events hvNotes
- #tag Event
- Function NewWindow() As HTMLViewer
- return hvNewWindow
- End Function
- #tag EndEvent
- #tag Event
- Function CancelLoad(URL as String) As Boolean
- dim r as boolean = not Loading
- Loading = false
- return r
-
- #pragma unused URL
- End Function
- #tag EndEvent
- #tag Event
- Sub Error(errorNumber as Integer, errorMessage as String)
- break
-
- #pragma unused errorNumber
- #pragma unused errorMessage
- End Sub
- #tag EndEvent
-#tag EndEvents
#tag Events btnOK
#tag Event
Sub Action()
@@ -1055,96 +1059,6 @@ End
End Sub
#tag EndEvent
#tag EndEvents
-#tag Events hsSocket
- #tag Event
- Sub ReceiveProgress(bytesReceived as integer, totalBytes as integer, newData as string)
- if CurrentStage = Stage.Cancelled then
- //
- // Do nothing
- //
- return
- end if
-
- //
- // Have to get the value below 65536
- //
-
- const kMaxAllowed = 1000
-
- if totalBytes > kMaxAllowed then
- dim mult as integer = totalBytes \ kMaxAllowed
- totalBytes = totalBytes \ mult
- bytesReceived = bytesReceived \ mult
- end if
-
- pbProgress.Maximum = totalBytes
- pbProgress.Value = bytesReceived
-
- tmrTimeout.Reset
-
- #pragma unused newData
- End Sub
- #tag EndEvent
- #tag Event
- Sub DownloadComplete(url as string, httpStatus as integer, headers as internetHeaders, file as folderItem)
- if CurrentStage = Stage.Cancelled then
- //
- // Do nothing
- //
- return
- end if
-
- pbProgress.Maximum = -1
- pbProgress.Value = 0
-
- tmrTimeout.Mode = Timer.ModeOff
-
- if httpStatus <> 200 then
-
- ShowError()
-
- elseif Kaju.HashOfFile( file ) <> SelectedBinary.Hash then
-
- ShowError( KajuLocale.kBadDownloadMessage )
-
- else
- //
- // We have the file and it appears to be good
- //
-
- lblInstallMessage.Text = KajuLocale.kProcessingFileMessage
-
- dim targetFolder as FolderItem
- #if TargetWindows then
- dim targetFolderName as string = SelectedUpdate.AppName + "- decompressed"
- targetFolder = App.ExecutableFile.Parent
- targetFolder = targetFolder.Child( targetFolderName )
- Kaju.DeleteRecursive( targetFolder )
- #else
- targetFolder = file.Parent.Child( "decompressed" )
- #endif
- DeleteOnCancel.Append targetFolder
- shZipper.Decompress( file, targetFolder )
- end if
-
-
- #pragma unused url
- #pragma unused headers
- End Sub
- #tag EndEvent
- #tag Event
- Sub Error(code as integer)
- if me.IsConnected then
- me.Disconnect
- end if
-
- tmrTimeout.Mode = Timer.ModeOff
-
- ShowError( KajuLocale.kGenericErrorMessage + " (" + str( code ) + ")" )
-
- End Sub
- #tag EndEvent
-#tag EndEvents
#tag Events shZipper
#tag Event
Sub DecompressCompleted(zipFile As FolderItem, containingFolder As FolderItem)
@@ -1183,7 +1097,7 @@ End
dim f as FolderItem = containingFolder.Item( i )
dim name as string = f.Name
dim leftChars as string = name.Left( 1 )
- if leftChars <> "." and leftChars <> "_" then
+ if leftChars <> "." and leftChars <> "_" and f.Directory then
item = f
exit
end if
@@ -1199,6 +1113,15 @@ End
Initiater.ReplacementAppFolder = item
Initiater.ReplacementExecutableName = SelectedBinary.ExecutableName
+ #if not TargetMacOS then
+ if Initiater.ReplacementExecutableName = "" then
+ //
+ // We will assume it's the same name
+ //
+ Initiater.ReplacementExecutableName = App.ExecutableFile.Name
+ end if
+ #endif
+
btnOK.Enabled = true
btnOK.Caption = KajuLocale.kQuitButton
btnCancel.Visible = true
@@ -1246,6 +1169,8 @@ End
// Fill in the viewer
//
+ CurrentUpdate = nil
+
if me.ListIndex = -1 then
if me.ListCount <> 0 then
me.ListIndex = 0
@@ -1255,6 +1180,7 @@ End
dim update as Kaju.UpdateInformation = me.RowTag( me.ListIndex )
DisplayVersionInfo( update )
+ CurrentUpdate = update
End Sub
#tag EndEvent
@@ -1262,57 +1188,178 @@ End
#tag Events tmrTimeout
#tag Event
Sub Action()
- if hsSocket.IsConnected then
- hsSocket.Disconnect
+ hsSocket.Disconnect
+ ShowError( KajuLocale.kTimedOutMessage )
+
+ End Sub
+ #tag EndEvent
+#tag EndEvents
+#tag Events hsSocket
+ #tag Event
+ Sub Error(e As RuntimeException)
+ tmrTimeout.Mode = Timer.ModeOff
+
+ dim errMsg as string = e.Message
+ if errMsg = "" then
+ errMsg = KajuLocale.kGenericErrorMessage
+ end if
+
+ ShowError( errMsg + " (" + str( e.ErrorNumber ) + ")" )
+
+ End Sub
+ #tag EndEvent
+ #tag Event
+ Sub FileReceived(URL As String, HTTPStatus As Integer, file As FolderItem)
+ #pragma unused url
+
+ if CurrentStage = Stage.Cancelled then
+ //
+ // Do nothing
+ //
+ return
+ end if
+
+ pbProgress.Maximum = -1
+ pbProgress.Value = 0
+
+ tmrTimeout.Mode = Timer.ModeOff
+
+ if httpStatus <> 200 then
+
+ ShowError()
+
+ elseif Kaju.HashOfFile( file ) <> SelectedBinary.Hash then
+
+ ShowError( KajuLocale.kBadDownloadMessage )
+
+ else
+ //
+ // We have the file and it appears to be good
+ //
+
+ lblInstallMessage.Text = KajuLocale.kProcessingFileMessage
+
+ dim targetFolder as FolderItem
+ #if TargetWindows then
+ dim targetFolderName as string = SelectedUpdate.AppName + "- decompressed"
+ targetFolder = App.ExecutableFile.Parent
+ targetFolder = targetFolder.Child( targetFolderName )
+ Kaju.DeleteRecursive( targetFolder )
+ #else
+ targetFolder = file.Parent.Child( "decompressed" )
+ #endif
+ DeleteOnCancel.Append targetFolder
+ shZipper.Decompress( file, targetFolder )
+ end if
+
+ End Sub
+ #tag EndEvent
+ #tag Event
+ Sub ReceivingProgressed(bytesReceived As Int64, totalBytes As Int64, newData As String)
+ #pragma unused newData
+
+ if CurrentStage = Stage.Cancelled then
+ //
+ // Do nothing
+ //
+ return
+ end if
+
+ //
+ // Have to get the value below 65536
+ //
+
+ const kMaxAllowed = 1000
+
+ if totalBytes > kMaxAllowed then
+ dim mult as integer = totalBytes \ kMaxAllowed
+ totalBytes = totalBytes \ mult
+ bytesReceived = bytesReceived \ mult
+ end if
+
+ pbProgress.Maximum = totalBytes
+ pbProgress.Value = bytesReceived
+
+ tmrTimeout.Reset
+
+
+ End Sub
+ #tag EndEvent
+#tag EndEvents
+#tag Events hvNotes
+ #tag Event
+ Function NewWindow() As Object
+ return hvNewWindow
+
+ End Function
+ #tag EndEvent
+ #tag Event
+ Function CancelLoad(URL as String) As Boolean
+ #pragma unused URL
+
+ dim r as boolean = not Loading
+ Loading = false
+ return r
+
+ End Function
+ #tag EndEvent
+ #tag Event
+ Sub Error(errorNumber as Integer, errorMessage as String)
+ #pragma unused errorMessage
+
+ #if TargetMacOS then
+ const kCancelledCode as integer = -999
+ #else
+ const kCancelledCode as integer = -9999999999
+ #endif
+
+ if errorNumber <> kCancelledCode then
+ break
end if
- ShowError( KajuLocale.kTimedOutMessage )
End Sub
#tag EndEvent
#tag EndEvents
#tag ViewBehavior
#tag ViewProperty
- Name="AppName"
- Group="Behavior"
- Type="String"
- EditorType="MultiLineEditor"
- #tag EndViewProperty
- #tag ViewProperty
- Name="BackColor"
+ Name="MinimumWidth"
Visible=true
- Group="Appearance"
- InitialValue="&hFFFFFF"
- Type="Color"
+ Group="Size"
+ InitialValue="64"
+ Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="Backdrop"
+ Name="MinimumHeight"
Visible=true
- Group="Appearance"
- Type="Picture"
- EditorType="Picture"
+ Group="Size"
+ InitialValue="64"
+ Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="CloseButton"
+ Name="MaximumWidth"
Visible=true
- Group="Appearance"
- InitialValue="True"
- Type="Boolean"
- EditorType="Boolean"
+ Group="Size"
+ InitialValue="32000"
+ Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="Composite"
+ Name="MaximumHeight"
Visible=true
- Group="Appearance"
- InitialValue="False"
- Type="Boolean"
+ Group="Size"
+ InitialValue="32000"
+ Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="Frame"
+ Name="Type"
Visible=true
- Group="Appearance"
+ Group="Frame"
InitialValue="0"
- Type="Integer"
+ Type="Types"
EditorType="Enum"
#tag EnumValues
"0 - Document"
@@ -1329,143 +1376,155 @@ End
#tag EndEnumValues
#tag EndViewProperty
#tag ViewProperty
- Name="FullScreen"
- Group="Appearance"
- InitialValue="False"
+ Name="HasCloseButton"
+ Visible=true
+ Group="Frame"
+ InitialValue="True"
Type="Boolean"
- EditorType="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="FullScreenButton"
+ Name="HasMaximizeButton"
Visible=true
- Group="Appearance"
- InitialValue="False"
+ Group="Frame"
+ InitialValue="True"
Type="Boolean"
- EditorType="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="HasBackColor"
+ Name="HasMinimizeButton"
Visible=true
- Group="Appearance"
+ Group="Frame"
+ InitialValue="True"
+ Type="Boolean"
+ EditorType=""
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="HasFullScreenButton"
+ Visible=true
+ Group="Frame"
InitialValue="False"
Type="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="Height"
+ Name="DefaultLocation"
Visible=true
- Group="Position"
- InitialValue="400"
- Type="Integer"
+ Group="Behavior"
+ InitialValue="0"
+ Type="Locations"
+ EditorType="Enum"
+ #tag EnumValues
+ "0 - Default"
+ "1 - Parent Window"
+ "2 - Main Screen"
+ "3 - Parent Window Screen"
+ "4 - Stagger"
+ #tag EndEnumValues
#tag EndViewProperty
#tag ViewProperty
- Name="ImplicitInstance"
+ Name="HasBackgroundColor"
Visible=true
- Group="Appearance"
- InitialValue="True"
+ Group="Background"
+ InitialValue="False"
Type="Boolean"
- EditorType="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="Interfaces"
+ Name="BackgroundColor"
Visible=true
- Group="ID"
+ Group="Background"
+ InitialValue="&hFFFFFF"
+ Type="Color"
+ EditorType="Color"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="AppName"
+ Visible=false
+ Group="Behavior"
+ InitialValue=""
Type="String"
- EditorType="String"
+ EditorType="MultiLineEditor"
#tag EndViewProperty
#tag ViewProperty
- Name="LiveResize"
+ Name="Backdrop"
Visible=true
Group="Appearance"
- InitialValue="True"
- Type="Boolean"
- EditorType="Boolean"
+ InitialValue=""
+ Type="Picture"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="MacProcID"
+ Name="Composite"
Visible=true
Group="Appearance"
- InitialValue="0"
- Type="Integer"
+ InitialValue="False"
+ Type="Boolean"
+ EditorType=""
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="FullScreen"
+ Visible=false
+ Group="Appearance"
+ InitialValue="False"
+ Type="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="MaxHeight"
+ Name="Height"
Visible=true
Group="Position"
- InitialValue="32000"
+ InitialValue="400"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="MaximizeButton"
+ Name="ImplicitInstance"
Visible=true
Group="Appearance"
InitialValue="True"
Type="Boolean"
- EditorType="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="MaxWidth"
+ Name="Interfaces"
Visible=true
- Group="Position"
- InitialValue="32000"
+ Group="ID"
+ InitialValue=""
+ Type="String"
+ EditorType=""
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="MacProcID"
+ Visible=true
+ Group="Appearance"
+ InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="MenuBar"
Visible=true
Group="Appearance"
+ InitialValue=""
Type="MenuBar"
- EditorType="MenuBar"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="MenuBarVisible"
+ Visible=false
Group="Appearance"
InitialValue="True"
Type="Boolean"
- EditorType="Boolean"
- #tag EndViewProperty
- #tag ViewProperty
- Name="MinHeight"
- Visible=true
- Group="Position"
- InitialValue="64"
- Type="Integer"
- #tag EndViewProperty
- #tag ViewProperty
- Name="MinimizeButton"
- Visible=true
- Group="Appearance"
- InitialValue="True"
- Type="Boolean"
- EditorType="Boolean"
- #tag EndViewProperty
- #tag ViewProperty
- Name="MinWidth"
- Visible=true
- Group="Position"
- InitialValue="64"
- Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
- EditorType="String"
- #tag EndViewProperty
- #tag ViewProperty
- Name="Placement"
- Visible=true
- Group="Position"
- InitialValue="0"
- Type="Integer"
- EditorType="Enum"
- #tag EnumValues
- "0 - Default"
- "1 - Parent Window"
- "2 - Main Screen"
- "3 - Parent Window Screen"
- "4 - Stagger"
- #tag EndEnumValues
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Resizeable"
@@ -1473,14 +1532,15 @@ End
Group="Appearance"
InitialValue="True"
Type="Boolean"
- EditorType="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
- EditorType="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Title"
@@ -1488,6 +1548,7 @@ End
Group="Appearance"
InitialValue="Untitled"
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Visible"
@@ -1495,7 +1556,7 @@ End
Group="Appearance"
InitialValue="True"
Type="Boolean"
- EditorType="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Width"
@@ -1503,5 +1564,6 @@ End
Group="Position"
InitialValue="600"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag EndViewBehavior
diff --git a/Kaju Update Test v1.kaju b/Kaju Update Test v1.kaju
index 9cc358e..1798d16 100644
--- a/Kaju Update Test v1.kaju
+++ b/Kaju Update Test v1.kaju
@@ -5,165 +5,175 @@
"KajuData":[
{
"AppName":"Kaju Update Test",
+ "ImageScale":1,
"ImageURL":"",
"MinimumRequiredVersion":"",
"ReleaseNotes":"
This is a fake update for v.1.1 (10). It will really point to a binary of 1.0. (This demonstrates the use of the optional build number for final versions.)<\/p>\n\r
In other words, the app will replace itself.<\/p>\n\n
NOTE<\/b>: The update will warn you that the update will require a payment. THIS IS A LIE!!<\/u> It’s only set that way to test the “Requires Payment” option.<\/p>\n\n 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>",
+ "ReleaseNotes":" A phony development version pointing to the same binary. Meant as a placeholder to demonstrate multiple versions.<\/p>\n Visit my web site<\/a>!<\/p>\n Note that this version has a name change.<\/p>",
"RequiresPayment":false,
"UseTransparency":false,
"Version":"1.2.2d5",
+ "Security Token":"9zSMiiEIxNQ=",
"MacBinary":{
- "Hash":"FAE717E57CDA429B80354D111A02F462",
+ "Hash":"5A66CD3648FC633C2CC3AC57FBB4CA80",
"URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Mac.zip"
},
"WindowsBinary":{
- "Hash":"3B03F9EB5303C7BBEA218B25C3D1A70C",
+ "Hash":"ECECC37A150B297CDB69EC32813136F6",
"URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Win.zip",
"ExecutableName":"Kaju Update Test.exe"
},
"LinuxBinary":{
- "Hash":"12F76303CED60E293A3E33D80F682282",
+ "Hash":"A386E0321651CFA41C7544D91BB8AACE",
"URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Linux.zip",
"ExecutableName":"Kaju Update Test"
},
"WindowsBinary64bit":{
- "Hash":"181779AD10242CB19EA36DBFA948C85D",
+ "Hash":"8225FE35A48D461638092DE9286A43DA",
"URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Win_64.zip",
"ExecutableName":"Kaju Update Test.exe"
},
"LinuxBinary64bit":{
- "Hash":"273B9E735AB4C9E6A371159A759A0610",
+ "Hash":"864E7E6D1E48B0E09ADD1D8CC6F76C08",
"URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Linux_64.zip",
"ExecutableName":"Kaju Update Test"
}
},
{
"AppName":"Kaju Update Test",
+ "ImageScale":1,
"ImageURL":"",
"MinimumRequiredVersion":"",
"ReleaseNotes":"\n\n\n\n These are alternate release notes. If the URL above can’t be accessed or returns an empty string, this will be displayed instead.<\/p>\n\n Try fiddling with the URL to see the results.<\/p>",
"RequiresPayment":false,
"UseTransparency":false,
"Version":"1.2.1a4",
+ "Security Token":"H\/kUzLP5Bgw=",
"MacBinary":{
- "Hash":"FAE717E57CDA429B80354D111A02F462",
+ "Hash":"5A66CD3648FC633C2CC3AC57FBB4CA80",
"URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Mac.zip"
},
"WindowsBinary":{
- "Hash":"3B03F9EB5303C7BBEA218B25C3D1A70C",
+ "Hash":"ECECC37A150B297CDB69EC32813136F6",
"URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Win.zip",
"ExecutableName":"Kaju Update Test.exe"
},
"LinuxBinary":{
- "Hash":"12F76303CED60E293A3E33D80F682282",
+ "Hash":"A386E0321651CFA41C7544D91BB8AACE",
"URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Linux.zip",
"ExecutableName":"Kaju Update Test"
},
"WindowsBinary64bit":{
- "Hash":"181779AD10242CB19EA36DBFA948C85D",
+ "Hash":"8225FE35A48D461638092DE9286A43DA",
"URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Win_64.zip",
"ExecutableName":"Kaju Update Test.exe"
},
"LinuxBinary64bit":{
- "Hash":"273B9E735AB4C9E6A371159A759A0610",
+ "Hash":"864E7E6D1E48B0E09ADD1D8CC6F76C08",
"URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Linux_64.zip",
"ExecutableName":"Kaju Update Test"
}
},
{
"AppName":"Kaju Update Test",
- "ImageURL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Some_Image_beta.png",
+ "ImageScale":2,
+ "ImageURL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/plush-bears-beta@2x.png",
"MinimumRequiredVersion":"",
"ReleaseNotes":" A phony beta pointing to the same binary. Meant as a placeholder to demonstrate multiple versions.<\/p>\n\n IMPORTANT<\/b>: The URL’s for the binaries have been intentionally switched to test the hash function. Attempting to update to this version should result in an error.<\/b>",
"RequiresPayment":false,
"UseTransparency":true,
"Version":"1.2b2",
+ "Security Token":"ZrBKzGbbyxg=",
"MacBinary":{
- "Hash":"FAE717E57CDA429B80354D111A02F462",
+ "Hash":"5A66CD3648FC633C2CC3AC57FBB4CA80",
"URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Linux.zip"
},
"WindowsBinary":{
- "Hash":"3B03F9EB5303C7BBEA218B25C3D1A70C",
+ "Hash":"ECECC37A150B297CDB69EC32813136F6",
"URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Mac.zip",
"ExecutableName":"Kaju Update Test.exe"
},
"LinuxBinary":{
- "Hash":"12F76303CED60E293A3E33D80F682282",
+ "Hash":"A386E0321651CFA41C7544D91BB8AACE",
"URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Win.zip",
"ExecutableName":"Kaju Update Test"
},
"WindowsBinary64bit":{
- "Hash":"181779AD10242CB19EA36DBFA948C85D",
+ "Hash":"8225FE35A48D461638092DE9286A43DA",
"URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Linux_64.zip",
"ExecutableName":"Kaju Update Test.exe"
},
"LinuxBinary64bit":{
- "Hash":"273B9E735AB4C9E6A371159A759A0610",
+ "Hash":"864E7E6D1E48B0E09ADD1D8CC6F76C08",
"URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Win_64.zip",
"ExecutableName":"Kaju Update Test"
}
},
{
"AppName":"Kaju Update Test",
+ "ImageScale":1,
"ImageURL":"",
"MinimumRequiredVersion":"",
"ReleaseNotes":" A fake release that should never appear. (Except in Preview.)<\/p>",
"RequiresPayment":false,
"UseTransparency":false,
"Version":"0.9",
+ "Security Token":"e9Lkuplq9ho=",
"MacBinary":{
- "Hash":"FAE717E57CDA429B80354D111A02F462",
+ "Hash":"5A66CD3648FC633C2CC3AC57FBB4CA80",
"URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Mac.zip"
},
"WindowsBinary":{
- "Hash":"3B03F9EB5303C7BBEA218B25C3D1A70C",
+ "Hash":"ECECC37A150B297CDB69EC32813136F6",
"URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Win.zip",
"ExecutableName":"Kaju Update Test.exe"
},
"LinuxBinary":{
- "Hash":"12F76303CED60E293A3E33D80F682282",
+ "Hash":"A386E0321651CFA41C7544D91BB8AACE",
"URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Linux.zip",
"ExecutableName":"Kaju Update Test"
},
"WindowsBinary64bit":{
- "Hash":"181779AD10242CB19EA36DBFA948C85D",
+ "Hash":"8225FE35A48D461638092DE9286A43DA",
"URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Win_64.zip",
"ExecutableName":"Kaju Update Test.exe"
},
"LinuxBinary64bit":{
- "Hash":"273B9E735AB4C9E6A371159A759A0610",
+ "Hash":"864E7E6D1E48B0E09ADD1D8CC6F76C08",
"URL":"http:\/\/www.mactechnologies.com\/Kaju_Test\/Kaju_Update_Test_Linux_64.zip",
"ExecutableName":"Kaju Update Test"
}
diff --git a/README.md b/README.md
index f9650b0..8b4e742 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ Kaju is a pull system where the client application gets information from a known
### Installation
-Open the included Admin App or Test App, copy the Kaju Classes folder, then paste it into your project.
+Open the included Admin App or Test App, copy the Kaju Classes folder, then paste it into your project. **Important**: Do not drag the folders directly from the directory.
### Special Actions
@@ -39,17 +39,29 @@ If you plan to allow 32-bit to 64-bit updates on Windows and Linux, you must inc
Create a new `Kaju.UpdateChecker` instance and fill in its properties. In the `Constructor`, you have to provide a FolderItem for a folder where Kaju can save its preferences, one that is unique to your app. At the least, you must also set the `ServerPublicRSAKey` (more on this later) and the `UpdateURL` where it will get its update information. If that URL (or any URL) starts with "https:", it will be accessed securely. (Conversely, a URL that does not start with "https:" will be accessed normally.)
-Call the `Execute` method of the `Kaju.UpdateChecker`. That's it. Kaju will handle everything else by going to the `UpdateURL` to see if there are any updates available for that version of the app, then ask the user about them. If the user chooses to update, the class will download and verify the binary, then offer the user the opportunity to Quit & Install or Cancel. If they choose to install, Quit will be called.
+**Note**: Due to changes in the MacOS, accessing an insecure URL will require entries in your app's plist file. For more information, look [here](https://docs.xojo.com/UserGuide:App_Transport_Security).
+
+Call the `ExecuteAsync` (preferred) or `Execute` method of the `Kaju.UpdateChecker`. That's it. Kaju will handle everything else by going to the `UpdateURL` to see if there are any updates available for that version of the app, then ask the user about them. If the user chooses to update, the class will download and verify the binary, then offer the user the opportunity to Quit & Install or Cancel. If they choose to install, Quit will be called.
Since none of this is modal, the user can continue to use your app with the update window waiting in the background. If they do choose to install, the update window will be sent to the back so it will be closed last.
-To discover what `UpdateChecker` found, you can check the `Result` method after calling `Execute`. It returns a value from the `Kaju.UpdateChecker.ResultType` enum.
+To discover what `UpdateChecker` found, you can check the `Result` property in the `ExecuteAsyncComplete` event after using `ExecuteAsync` (preferred) or directly after calling `Execute`. It returns a value from the `Kaju.UpdateChecker.ResultType` enum. If there was a connection error with `ExecuteAsync` check the `LastError` property too.
+
+### ExecuteAsync vs. Execute
+
+Kaju has two ways to start the update process, `Kaju.UpdateChecker.ExecuteAsync` and `Kaju.UpdateChecker.Execute`.
+
+Xojo has introduced the `URLConnection` class, an update to the classic `HTTPSocket` and `HTTPSecureSocket` classes. The more modern implementation is preferred and used when you choose `ExecuteAsync`. The older class is used when you choose the synchronous `Execute` _and_ set `AllowRedirection` to `False` (Unfortunately, the `URLConnection` class has no way to disallow redirects and we can only fake it in asynchronous mode.)
+
+`ExecuteAsync` will report its result in the `ExecuteAsyncComplete` event while `Execute` will report its results immediately.
+
+If your update information is not on a secure website, it shouldn't matter which you use, but we still recommend `ExecuteAsync` moving forward.
### Minimum OS
Kaju will work the same way on Mac, Windows, and Linux. All recent versions of MacOS and Linux should be supported. Windows Vista and later are supported.
-If Kaju cannot find the tools it needs, the `Result` will be set to `UnsupportedOS` after you call `Execute`.
+If Kaju cannot find the tools it needs, the `Result` will be set to `UnsupportedOS` after you call `ExecuteAsync` or `Execute`.
**Important**: Recent Linus distros do not have the libraries needed to show the `HTMLViewer` in 32-bit apps. Kaju will report an error in those cases and will not show the release notes, but the update will still work.
@@ -57,9 +69,9 @@ If Kaju cannot find the tools it needs, the `Result` will be set to `Unsupported
### Required Updates
-If you set up a minimim required version in your update information, Kaju may find that a particular update is "required". For example, if the user is using v.1.0 and you've discovered a bug that necessitates an update to at least v.1.1, you would set that as the minimum required version. In the future, even as you release v.1.2, 1.3, etc, you would leave the minimum required as v.1.1 so Kaju knows to force the users of 1.0 to update.
+If you set up a minimum required version in your update information, Kaju may find that a particular update is "required". For example, if the user is using v.1.0 and you've discovered a bug that necessitates an update to at least v.1.1, you would set that as the minimum required version. In the future, even as you release v.1.2, 1.3, etc, you would leave the minimum required as v.1.1 so Kaju knows to force the users of 1.0 to update.
-After calling `Kaju.UpdateChecker.Execute`, the `Result` method will tell you if a required update was found. In that case, it's up to you to take special actions to make sure that your app cannot be used until it is updated. To help, there is the `Kaju.UpdateChecker.QuitOnCancelIfRequired` property that is `True` by default. If the user tries to cancel a required update, the app will quit.
+After calling `Kaju.UpdateChecker.ExecuteAsync` or `Kaju.UpdateChecker.Execute`, the `Result` property will tell you if a required update was found. In that case, it's up to you to take special actions to make sure that your app cannot be used until it is updated. To help, there is the `Kaju.UpdateChecker.QuitOnCancelIfRequired` property that is `True` by default. If the user tries to cancel a required update, the app will quit.
### Other Features
@@ -71,11 +83,11 @@ If an update was found, the update window will have opened. You can check throug
The user can choose to ignore certain versions as long as they are not marked as required. You can set `HonorIgnored` to `False` to bypass that temporarily and present even ignored versions to your user, or you can clear the database of ignored versions entirely with the `ResetIgnored` method.
-You may choose to specify an update URL that redirects to another location. By default, Kaju will not allow that, but if you really need to do it, set the `Kaju.UpdateChecker.AllowRedirection` property to `True`.
+You may choose to specify an update URL that redirects to another location. By default, Kaju will not allow that, but if you really need to do it, set the `Kaju.UpdateChecker.AllowRedirection` property to `True`.
### One At A Time
-You can create several instances of `Kaju.UpdateChecker` if you'd like, but only one update can run at any time. If an update is already in progress, `Execute` won't do anything and will let you know through the `Result`.
+You can create several instances of `Kaju.UpdateChecker` if you'd like, but only one update can run at any time. If an update is already in progress, `ExecuteAsync` and `Execute` won't do anything and will let you know through the `Result`.
### Images
@@ -85,13 +97,15 @@ You can also set `Kaju.UpdateChecker.DefaultUseTransparency` or set "Use Transpa
An image will cover the entire window without cropping or scaling starting at the upper, left corner. Accordingly, you can provide an entire background image or just an icon.
+Within your app, use an Image Set to properly handle HiRes vs. LoRes screens. When providing a URL, set the "Scale" property for the image. For example, the URL points to an image designed for HiRes displays, set the Scale to 2 or 3, as appropriate, and Kaju will scale for LoRes if needed.
+
### Limitations
Kaju does not elevate permissions. If the user does not have write permission for the executable or its parent, `ResultType.NoWritePermission` will be returned in `Kaju.UpdateChecker.Result`.
### Platform Differences
-Kaju will act the same way across plaforms except for one point: Since the Mac executable is always one package, it will be replaced entirely. Anything stored within the package that was put there after initial installation will be deleted.
+Kaju will act the same way across platforms except for one point: Since the Mac executable is always one package, it will be replaced entirely. Anything stored within the package that was put there after initial installation will be deleted.
On Windows and Linux, since executable folders can be combined, only the files that are found in the update will be replaced. Any additional files or even older, no-longer-used files, will remain untouched. If you want to make sure some older file is removed by the update, put an empty placeholder into the update package.
@@ -108,7 +122,7 @@ dim updater as new Kaju.UpdateChecker( myAppPrefFolder )
updater.ServerPublicRSAKey = "12345..." // The key you copied from the Admin app
updater.UpdateURL = "http://www...." // Where the update info will be posted
-updater.Execute
+updater.ExecuteAsync
```
* If you expect to allow 32-bit to 64-bit updates on Windows or Linux, insert code into `App.Open` that will force the user to manually restart the app if such an update is detected. See the Kaju Update Test app project code for an example.
@@ -117,7 +131,7 @@ At a bare minimum, that's it.
## The Admin App
-The included Admin app makes it easy to set up your update file. Start it up and use the "+" at the bottom, left to add a version. Fill in the information for the release.
+The included Admin app makes it easy to set up your update file. Start it up and use the "+" at the bottom, left to add a version. Fill in the information for the release.
When you're done, save the file, then export the HTML data. It is this exported file that you will post to your web site and the final URL should match the URL you included within your app.
@@ -127,7 +141,26 @@ Add an entry for each *current* version of your app. You do not need a history s
The release notes are created in HTML and some simple tools are provided for making that a bit easier. You can see a preview of the release notes as a you type and use the Preview button to see how Kaju will present the update window under various circumstances. The HTML can be as simple or as complex as you'd like.
-Alternatively, you can pull your release notes from a server by setting the first line to a URL. Anything after the first line will be used as an alternate if the URL can't be reached or has no content. (But note: Older apps with Kaju 1.x will see the text of the release notes including the URL at the top.)
+Alternatively, you can pull your release notes from a server by setting the first line to a URL. Anything after the first line will be used as an alternate if the URL can't be reached or has no content. (But note: Older apps with Kaju 1.x will see the text of the release notes including the URL at the top _unless_ that URL is in a comment.)
+
+The two ways to include a URL from which release notes will be pulled:
+
+```
+http://wwww.something.com/my_release_notes
+
+These are the alternate release notes and
+the url above will be visible.
+```
+
+or
+
+```
+
+
+These are the alternate release notes but
+the url above will not be visible because they are
+commented (preferred).
+```
**Note**: WebKit is used on all platforms to ensure consistency. This will increase the size of your project on Windows and Linux.
@@ -145,6 +178,8 @@ For each version in your admin file, check the checkbox for each platform to whi
For Windows and Linux, you must also provide the exact name of the executable. If your app is called "My Great App", the Linux executable name will be "My Great App" and the Windows name will be "My Great App.exe".
+__Note__: If you omit this, Kaju will assume the name of the executable that is running the update.
+
### About 64-bit
Kaju will allow you to specify 64-bit versions for Windows and Linux. If available, and if the `UpdateChecker.Allow32bitTo64bitUpdates` is `True`, the users of your 32-bit version will be given the option to upgrade to the next version as 64-bit. *But* see the warning above in that case.
@@ -194,6 +229,7 @@ The JSON will contain these fields for each version.
URL (string)
Hash (string)
ImageURL (string)
+ ImageScale (integer)
UseTransparency (bool, default = true)
A sample JSON that will be returned by the server:
@@ -222,7 +258,7 @@ A sample JSON that will be returned by the server:
"URL" : "http://www.site.com/download_path_Linux" ,
"Hash" : "ABC123"
} ,
- "WindowsBinaryb4bit" :
+ "WindowsBinary64bit" :
{
"ExecutableName" : "My App.exe" ,
"URL" : "http://www.site.com/download_path_Win_64" ,
@@ -235,19 +271,20 @@ A sample JSON that will be returned by the server:
"Hash" : "ABC12C"
} ,
"ImageURL" : "http://www.site.com/image.png" ,
+ "ImageScale" : 2 ,
"UseTransparency" : true
} ,
{
"AppName" : "My App" ,
"Version" : "6.1b4" ,
"ReleaseNotes" : "http://link/to/release/notes" ,
- "MacBinary" :
+ "MacBinary" :
{
"URL" : "http://www.site.com/other_download_path" ,
"Hash" :"0123456"
- }
+ }
}
-]
+]
```
**NOTE**: The ExecutableName will be used by the updater script while the AppName is what will display in the updater window. These may be the same or different. Since the ExecutableName of the Mac app can be discovered, it is not needed for the Mac binary.
@@ -290,6 +327,7 @@ There is also a `Kaju.Version` constant (introduced in v.1.4) that will let you
|DefaultImage|Picture|The background image that will be displayed in the window when an image is not provided by the update|n|
|DefaultUseTransparency|Boolean|If `True`, transparency will be set to 50%|n|
|HonorIgnored|Boolean|If `False`, the user will be presented with updates they previously set to "ignore" (default: `True`)|n|
+|LastError|RuntimeException|Stores an error returned by `ExecuteAsync`|n/a|
|QuitOnCancelIfRequired|Boolean|When `True` (default), canceling a required update will call Quit|n|
|ServerPublicRSAKey|String|The public key as found in the Admin app file|**yes**|
|UpdateURL|String|The URL where the update info will be found|**yes**|
@@ -298,7 +336,8 @@ There is also a `Kaju.Version` constant (introduced in v.1.4) that will let you
|Method|Description|
|:-----|:---------|
|Constructor(preferencesFolder As FolderItem[, preferencesFilename As String])|Create the new instance around the given preferences folder using the given name for the file if provided, or "Kaju_Preferences" if not|
-|Execute|Start the update process|
+|ExecuteAsync|Start the update process asynchronously (preferred)|
+|Execute|Start the update process synchronously|
|ResetIgnored|Reset the list of ignored updates|
|Result As ResultType|The result of the last Execute|
@@ -306,6 +345,11 @@ There is also a `Kaju.Version` constant (introduced in v.1.4) that will let you
|:---|:---|
|OSIsSupported As Boolean|Reports if the OS has the right tools installed|
+|Event|Description|
+|:----|:----------|
+|ExecuteAsyncComplete|`ExecuteAsync` has checked the update information packet from the `UpdateURL` and is reporting some result or status. Check `Result` and, if necessary, `LastError`.|
+
+
**Module:** `Kaju`
|Method|Description|
@@ -335,7 +379,7 @@ Translations to other languages by:
* Sascha Schneppmueller (German)
* Valdemar De SOUSA (French)
* Julen Ibarretxe Uriguen (Spanish)
-* Heikki Ohvo (Finnish)
+* Heikki Hoo (Finnish)
* Manuel Romei (Italian)
* Vidal van Bergen (Dutch)
@@ -369,13 +413,38 @@ Fork the project to your GitHub account. Use the "develop" branch for general fi
There are two places to look for strings that need translation:
-1. The constants in the KajuLocale module.
+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
+2.1 (July 3, 2020)
+
+* **KajuUpdateWindow**: Changed `hsSocket` to a `URLConnection` object.
+* **UpdateChecker**: Added `ExecuteAsync` that will check for updates asynchronously using `URLConnection` and `LastError` for HTTP errors that occur when using that method.
+* **UpdateChecker**: Deprecated `Execute`.
+* **UpdateChecker**: Use `URLConnection` unless `Execute` is used where `AllowRedirection` isß `False`.
+* **UpdateChecker**: Added results for "PageNotFound", "PageRedirected", and "FetchingUpdateInfo".
+* **UpdateChecker**: Better handling of a URL in the form "http://un:pw@path".
+* **UpdateChecker**: Changed `Result` to a read-only computed property and made the `mResult` shadow property hidden.
+* **UpdateChecker**: Removed events that were not being raised anyway.
+* **UpdateChecker**: Make sure each version has a security token (see below).
+* **UpdateChecker**: Validate the downloaded packet against every form of EOL with and without Trim in case that got changed along the way.
+* **UpdateChecker**: `OSIsSupported` will try twice to find the tools it needs and log any errors.
+* **UpdateInformation**: Will fetch images and release notes asynchronously.
+* **UpdateInitiater**: Fixed Windows script issue that could have prevented re-launch of the application.
+* **Test App**: The window will let you specify Asynchronous and your own URL and/or public key. It will also allow testing of simple HTTP authenticated directories.
+* **Test App**: Asynchronous is now the default.
+* **Admin App**: Fixed issues with saving and alias tracking. (Alias tracking does not work on Windows.)
+* **Admin App**: Better UI handling on Windows.
+* **General**: Code changes for easier debugging.
+* **General**: All HTTP requests now include headers to disable caching.
+* **General**: Exported information file contains a security token to make sure that each export has a different RSA signature.
+* **General**: Handle IOException.
+* **General**: Updated build script to look for kaju cli in "Builds" folder as named in the newer Xojo versions.
+
2.0 (May 31, 2017)
* **CLI**: Made help prettier.
@@ -386,7 +455,7 @@ Add a translation for each, then submit a pull request as outlined above.
* Ability to load release notes through a URL.
* **Admin GUI**: Fixed Dupe button.
* Added support for 64-bit binaries.
-* **Kaju**: Changed parameters of `DidLastUpdateSucceed` to report the "bit-ness" of the version that initiated the update.
+* **Kaju**: Changed parameters of `DidLastUpdateSucceed` to report the "bit-ness" of the version that initiated the update.
* **Test App**: Use better technique for compressing Windows and Linux executables.
1.6.1 (August 27, 2015)
@@ -477,4 +546,3 @@ Add a translation for each, then submit a pull request as outlined above.
1.0 (Jan. 5, 2015)
* Initial release.
-
diff --git a/Update Test App/Build Scripts/Prepare Kaju.xojo_script b/Update Test App/Build Scripts/Prepare Kaju.xojo_script
index ae733bd..8fcee99 100644
--- a/Update Test App/Build Scripts/Prepare Kaju.xojo_script
+++ b/Update Test App/Build Scripts/Prepare Kaju.xojo_script
@@ -53,10 +53,17 @@ case else
print str( CurrentBuildTarget )
end select
-dim kaju as string = topLevelPath + "/Kaju\ Admin\ CLI/Builds\ \-\ Kaju\ Admin\ CLI.xojo_project/Mac\ OS\ X\ \(Intel\)/kaju/kaju"
+dim kaju as string
+kaju = topLevelPath + "/Kaju\ Admin\ CLI/Builds\ \-\ Kaju\ Admin\ CLI/OS\ X\ 64\ bit/kaju/kaju"
dim result as string
result = DoShellCommand( kaju )
+
+if result.InStr( "addversion" ) = 0 then
+kaju = topLevelPath + "/Kaju\ Admin\ CLI/Builds\ \-\ Kaju\ Admin\ CLI.xojo_project/OS\ X\ 64\ bit/kaju/kaju"
+result = DoShellCommand( kaju )
+end if
+
if result.InStr( "addversion" ) = 0 then
print "The kaju CLI is not available. Build it first."
return
diff --git a/Update Test App/Kaju Update Test.xojo_project b/Update Test App/Kaju Update Test.xojo_project
index bd9c006..3f30e18 100644
--- a/Update Test App/Kaju Update Test.xojo_project
+++ b/Update Test App/Kaju Update Test.xojo_project
@@ -1,24 +1,28 @@
Type=Desktop
-RBProjectVersion=2017.011
-MinIDEVersion=20070100
-Class=App;App.xojo_code;&h503AC7A0;&h0;false
-Window=Window1;Window1.xojo_window;&h4308442C;&h0;false
-MenuBar=MainMenuBar;MainMenuBar.xojo_menu;&h671CDA54;&h0;false
-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
-Class=HTTPSSocket;../Kaju Classes/Kaju/HTTPSSocket.xojo_code;&h5ACDFAEB;&h11400316;false
-Class=BinaryInformation;../Kaju Classes/Kaju/BinaryInformation.xojo_code;&hE8D70B5;&h11400316;false
-Class=ZipShell;../Kaju Classes/Kaju/ZipShell.xojo_code;&hCC15E9B;&h11400316;false
-Class=Information;../Kaju Classes/Kaju/Information.xojo_code;&h6497A7C4;&h11400316;false
-Class=UpdateInitiater;../Kaju Classes/Kaju/UpdateInitiater.xojo_code;&h4DBB48E5;&h11400316;false
-Window=KajuUpdateWindow;../Kaju Classes/KajuUpdateWindow.xojo_window;&h18AE3D9;&h2570CF64;false
-DefaultWindow=Window1
+RBProjectVersion=2019.031
+MinIDEVersion=20150400
+OrigIDEVersion=00000000
+Class=App;App.xojo_code;&h00000000503AC7A0;&h0000000000000000;false
+Folder=Custom Plist;Custom Plist;&h0000000031A617FF;&h0000000000000000;false
+Window=WndTest;WndTest.xojo_window;&h000000004308442C;&h0000000000000000;false
+MenuBar=MainMenuBar;MainMenuBar.xojo_menu;&h00000000671CDA54;&h0000000000000000;false
+MultiImage=Some_Image;Some_Image.xojo_image;&h00000000516477FF;&h0000000000000000;false
+BuildSteps=Build Automation;Build Automation.xojo_code;&h0000000017423755;&h0000000000000000;false
+Folder=Kaju Classes;../Kaju Classes;&h000000002570CF64;&h0000000000000000;false
+Module=Kaju;../Kaju Classes/Kaju.xojo_code;&h0000000011400316;&h000000002570CF64;false
+Module=KajuLocale;../Kaju Classes/KajuLocale.xojo_code;&h00000000020D2554;&h000000002570CF64;false
+Class=UpdateChecker;../Kaju Classes/Kaju/UpdateChecker.xojo_code;&h0000000070CF0A50;&h0000000011400316;false
+Class=KajuException;../Kaju Classes/Kaju/KajuException.xojo_code;&h000000003047231F;&h0000000011400316;false
+Class=UpdateInformation;../Kaju Classes/Kaju/UpdateInformation.xojo_code;&h0000000079AE1ADC;&h0000000011400316;false
+Class=HTTPSSocket;../Kaju Classes/Kaju/HTTPSSocket.xojo_code;&h000000005ACDFAEB;&h0000000011400316;false
+Class=HTTPSocketAsync;../Kaju Classes/Kaju/HTTPSocketAsync.xojo_code;&h000000006C1487FF;&h0000000011400316;false
+Class=BinaryInformation;../Kaju Classes/Kaju/BinaryInformation.xojo_code;&h000000000E8D70B5;&h0000000011400316;false
+Class=ZipShell;../Kaju Classes/Kaju/ZipShell.xojo_code;&h000000000CC15E9B;&h0000000011400316;false
+Class=Information;../Kaju Classes/Kaju/Information.xojo_code;&h000000006497A7C4;&h0000000011400316;false
+Class=UpdateInitiater;../Kaju Classes/Kaju/UpdateInitiater.xojo_code;&h000000004DBB48E5;&h0000000011400316;false
+Window=KajuUpdateWindow;../Kaju Classes/KajuUpdateWindow.xojo_window;&h00000000018AE3D9;&h000000002570CF64;false
+Plist=Info;../Custom Plist/Info.plist;&h00000000418787FF;&h0000000031A617FF;false
+DefaultWindow=WndTest
AppMenuBar=MainMenuBar
MajorVersion=1
MinorVersion=0
@@ -50,9 +54,12 @@ DebuggerCommandLine=
UseGDIPlus=True
UseBuildsFolder=True
HiDPI=True
+DarkMode=True
CopyRedistNextToWindowsEXE=False
IsWebProject=False
LinuxBuildArchitecture=1
MacBuildArchitecture=1
WindowsBuildArchitecture=1
OptimizationLevel=0
+WindowsVersions={35138b9a-5d96-4fbd-8e2d-a2440225f93a}|{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}|{1f676c76-80e1-4239-95bb-83d0f6d0da78}|{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}
+WindowsRunAs=0
diff --git a/Update Test App/Some_Image.xojo_image b/Update Test App/Some_Image.xojo_image
new file mode 100644
index 0000000..1e4ceb9
--- /dev/null
+++ b/Update Test App/Some_Image.xojo_image
@@ -0,0 +1,46 @@
+#tag MultiImage
+Image Some_Image
+ #tag ImageRepresentation
+ SaveInfo = APHRcwECAQAAAAJgAAAAAAJgAAIAAAVBdGxhcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQkQAAf////8fcGx1c2gtYmVhcnMtdmVjdG9yI0ZGRkZGRkZGLnBuZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAAP////8AAAogY3UAAAAAAAAAAAAAAAAAD0V4dGVybmFsIEltYWdlcwAAAgCLLzpVc2VyczprdGVraW5heTpEb2N1bWVudHM6UkIgUHJvamVjdHM6S2FqdSBTZWxmLVVwZGF0ZXI6S2FqdSBHaXQ6RXh0ZXJuYWwgSW1hZ2VzOnBsdXNoLWJlYXJzLXZlY3Rvci1jbGlwYXJ0LWZyb20tZ29vZGZyZWVwaG90b3MtY29tQDF4LnBuZwAADgB0ADkAcABsAHUAcwBoAC0AYgBlAGEAcgBzAC0AdgBlAGMAdABvAHIALQBjAGwAaQBwAGEAcgB0AC0AZgByAG8AbQAtAGcAbwBvAGQAZgByAGUAZQBwAGgAbwB0AG8AcwAtAGMAbwBtAEAAMQB4AC4AcABuAGcADwAMAAUAQQB0AGwAYQBzABIAiVVzZXJzL2t0ZWtpbmF5L0RvY3VtZW50cy9SQiBQcm9qZWN0cy9LYWp1IFNlbGYtVXBkYXRlci9LYWp1IEdpdC9FeHRlcm5hbCBJbWFnZXMvcGx1c2gtYmVhcnMtdmVjdG9yLWNsaXBhcnQtZnJvbS1nb29kZnJlZXBob3Rvcy1jb21AMXgucG5nAAATAAEvAAAVAAIAD///AAAAAAAAAAA=
+ FullPath = /Users/ktekinay/Documents/RB Projects/Kaju Self-Updater/Kaju Git/External Images/plush-bears-vector-clipart-from-goodfreephotos-com@1x.png
+ PartialPath = ..\External Images\plush-bears-vector-clipart-from-goodfreephotos-com@1x.png
+ #tag ImageSpecification
+ Comment =
+ Device = 31
+ HSize = 800.00
+ Orientation = Any
+ Platform = 15
+ PPI = 72
+ VSize = 494.00
+ #tag EndImageSpecification
+ #tag EndImageRepresentation
+ #tag ImageRepresentation
+ SaveInfo = APHRcwECAQAAAAJgAAAAAAJgAAIAAAVBdGxhcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQkQAAf////8fcGx1c2gtYmVhcnMtdmVjdG9yI0ZGRkZGRkZGLnBuZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////wAAAABQTkdmR0tPTv////8AAAogY3UAAAAAAAAAAAAAAAAAD0V4dGVybmFsIEltYWdlcwAAAgCLLzpVc2VyczprdGVraW5heTpEb2N1bWVudHM6UkIgUHJvamVjdHM6S2FqdSBTZWxmLVVwZGF0ZXI6S2FqdSBHaXQ6RXh0ZXJuYWwgSW1hZ2VzOnBsdXNoLWJlYXJzLXZlY3Rvci1jbGlwYXJ0LWZyb20tZ29vZGZyZWVwaG90b3MtY29tQDJ4LnBuZwAADgB0ADkAcABsAHUAcwBoAC0AYgBlAGEAcgBzAC0AdgBlAGMAdABvAHIALQBjAGwAaQBwAGEAcgB0AC0AZgByAG8AbQAtAGcAbwBvAGQAZgByAGUAZQBwAGgAbwB0AG8AcwAtAGMAbwBtAEAAMgB4AC4AcABuAGcADwAMAAUAQQB0AGwAYQBzABIAiVVzZXJzL2t0ZWtpbmF5L0RvY3VtZW50cy9SQiBQcm9qZWN0cy9LYWp1IFNlbGYtVXBkYXRlci9LYWp1IEdpdC9FeHRlcm5hbCBJbWFnZXMvcGx1c2gtYmVhcnMtdmVjdG9yLWNsaXBhcnQtZnJvbS1nb29kZnJlZXBob3Rvcy1jb21AMngucG5nAAATAAEvAAAVAAIAD///AAAAAAAAAAA=
+ FullPath = /Users/ktekinay/Documents/RB Projects/Kaju Self-Updater/Kaju Git/External Images/plush-bears-vector-clipart-from-goodfreephotos-com@2x.png
+ PartialPath = ..\External Images\plush-bears-vector-clipart-from-goodfreephotos-com@2x.png
+ #tag ImageSpecification
+ Comment =
+ Device = 31
+ HSize = 800.00
+ Orientation = Any
+ Platform = 15
+ PPI = 144
+ VSize = 494.00
+ #tag EndImageSpecification
+ #tag EndImageRepresentation
+ #tag ImageRepresentation
+ SaveInfo = APHRcwECAQAAAAJgAAAAAAJgAAIAAAVBdGxhcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQkQAAf////8fcGx1c2gtYmVhcnMtdmVjdG9yI0ZGRkZGRkZGLnBuZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAAP////8AAAogY3UAAAAAAAAAAAAAAAAAD0V4dGVybmFsIEltYWdlcwAAAgCLLzpVc2VyczprdGVraW5heTpEb2N1bWVudHM6UkIgUHJvamVjdHM6S2FqdSBTZWxmLVVwZGF0ZXI6S2FqdSBHaXQ6RXh0ZXJuYWwgSW1hZ2VzOnBsdXNoLWJlYXJzLXZlY3Rvci1jbGlwYXJ0LWZyb20tZ29vZGZyZWVwaG90b3MtY29tQDN4LnBuZwAADgB0ADkAcABsAHUAcwBoAC0AYgBlAGEAcgBzAC0AdgBlAGMAdABvAHIALQBjAGwAaQBwAGEAcgB0AC0AZgByAG8AbQAtAGcAbwBvAGQAZgByAGUAZQBwAGgAbwB0AG8AcwAtAGMAbwBtAEAAMwB4AC4AcABuAGcADwAMAAUAQQB0AGwAYQBzABIAiVVzZXJzL2t0ZWtpbmF5L0RvY3VtZW50cy9SQiBQcm9qZWN0cy9LYWp1IFNlbGYtVXBkYXRlci9LYWp1IEdpdC9FeHRlcm5hbCBJbWFnZXMvcGx1c2gtYmVhcnMtdmVjdG9yLWNsaXBhcnQtZnJvbS1nb29kZnJlZXBob3Rvcy1jb21AM3gucG5nAAATAAEvAAAVAAIAD///AAAAAAAAAAA=
+ FullPath = /Users/ktekinay/Documents/RB Projects/Kaju Self-Updater/Kaju Git/External Images/plush-bears-vector-clipart-from-goodfreephotos-com@3x.png
+ PartialPath = ..\External Images\plush-bears-vector-clipart-from-goodfreephotos-com@3x.png
+ #tag ImageSpecification
+ Comment =
+ Device = 31
+ HSize = 800.00
+ Orientation = Any
+ Platform = 15
+ PPI = 216
+ VSize = 494.00
+ #tag EndImageSpecification
+ #tag EndImageRepresentation
+End Image
+#tag EndMultiImage
diff --git a/Update Test App/Window1.xojo_window b/Update Test App/WndTest.xojo_window
similarity index 59%
rename from Update Test App/Window1.xojo_window
rename to Update Test App/WndTest.xojo_window
index 1e88063..b21a088 100644
--- a/Update Test App/Window1.xojo_window
+++ b/Update Test App/WndTest.xojo_window
@@ -1,24 +1,23 @@
#tag Window
-Begin Window Window1
+Begin Window WndTest
BackColor = &cFFFFFF00
Backdrop = 0
CloseButton = True
- Compatibility = ""
Composite = False
Frame = 0
FullScreen = False
FullScreenButton= False
HasBackColor = False
- Height = 400
+ Height = 584
ImplicitInstance= True
- LiveResize = True
+ LiveResize = "True"
MacProcID = 0
- MaxHeight = 400
- MaximizeButton = True
+ MaxHeight = 584
+ MaximizeButton = False
MaxWidth = 600
MenuBar = 1729944148
MenuBarVisible = True
- MinHeight = 400
+ MinHeight = 584
MinimizeButton = True
MinWidth = 600
Placement = 0
@@ -48,7 +47,8 @@ Begin Window Window1
Selectable = False
TabIndex = 0
TabPanelIndex = 0
- Text = "This will check a predefined web site for an update. It will always show an update for 1.1 and offer to download it, but the download is, in fact, v.1.0. In other words, the app will replace itself (sometimes with an older version) just so the process can be repeated."
+ TabStop = True
+ Text = "This will check a predefined web site for an update. It will always show an update for X.1 and offer to download it, but the download is, in fact, the same version. In other words, the app will replace itself (sometimes with an older version) just so the process can be repeated."
TextAlign = 0
TextColor = &c00000000
TextFont = "System"
@@ -63,7 +63,7 @@ Begin Window Window1
Begin PushButton btnExecute
AutoDeactivate = True
Bold = False
- ButtonStyle = "0"
+ ButtonStyle = 0
Cancel = False
Caption = "Check"
Default = True
@@ -73,20 +73,21 @@ Begin Window Window1
Index = -2147483648
InitialParent = ""
Italic = False
- Left = 13
+ Left = 12
LockBottom = False
LockedInPosition= False
LockLeft = True
LockRight = False
LockTop = True
Scope = 0
- TabIndex = 1
+ TabIndex = 15
TabPanelIndex = 0
TabStop = True
TextFont = "System"
TextSize = 0.0
TextUnit = 0
- Top = 288
+ Top = 453
+ Transparent = True
Underline = False
Visible = True
Width = 129
@@ -111,13 +112,14 @@ Begin Window Window1
LockTop = True
Scope = 0
State = 1
- TabIndex = 2
+ TabIndex = 5
TabPanelIndex = 0
TabStop = True
TextFont = "System"
TextSize = 0.0
TextUnit = 0
- Top = 85
+ Top = 216
+ Transparent = True
Underline = False
Value = True
Visible = True
@@ -143,15 +145,16 @@ Begin Window Window1
Multiline = True
Scope = 0
Selectable = False
- TabIndex = 3
+ TabIndex = 16
TabPanelIndex = 0
+ TabStop = True
Text = "Press check to get a result"
TextAlign = 0
TextColor = &c00000000
- TextFont = "System"
+ TextFont = "SmallSystem"
TextSize = 0.0
TextUnit = 0
- Top = 300
+ Top = 461
Transparent = False
Underline = False
Visible = True
@@ -160,7 +163,7 @@ Begin Window Window1
Begin PushButton btnResetIgnored
AutoDeactivate = True
Bold = False
- ButtonStyle = "0"
+ ButtonStyle = 0
Cancel = False
Caption = "Reset Ignored"
Default = False
@@ -177,13 +180,14 @@ Begin Window Window1
LockRight = False
LockTop = True
Scope = 0
- TabIndex = 4
+ TabIndex = 6
TabPanelIndex = 0
TabStop = True
TextFont = "System"
TextSize = 0.0
TextUnit = 0
- Top = 85
+ Top = 216
+ Transparent = True
Underline = False
Visible = True
Width = 139
@@ -208,13 +212,14 @@ Begin Window Window1
LockTop = True
Scope = 0
State = 1
- TabIndex = 5
+ TabIndex = 7
TabPanelIndex = 0
TabStop = True
TextFont = "System"
TextSize = 0.0
TextUnit = 0
- Top = 117
+ Top = 248
+ Transparent = True
Underline = False
Value = True
Visible = True
@@ -240,13 +245,14 @@ Begin Window Window1
LockTop = True
Scope = 0
State = 1
- TabIndex = 6
+ TabIndex = 8
TabPanelIndex = 0
TabStop = True
TextFont = "System"
TextSize = 0.0
TextUnit = 0
- Top = 149
+ Top = 280
+ Transparent = True
Underline = False
Value = True
Visible = True
@@ -272,13 +278,14 @@ Begin Window Window1
LockRight = False
LockTop = True
Scope = 0
- TabIndex = 7
+ TabIndex = 11
TabPanelIndex = 0
TabStop = True
TextFont = "System"
TextSize = 0.0
TextUnit = 0
- Top = 181
+ Top = 373
+ Transparent = True
Underline = False
Visible = True
Width = 171
@@ -303,15 +310,16 @@ Begin Window Window1
Multiline = False
Scope = 0
Selectable = False
- TabIndex = 8
+ TabIndex = 12
TabPanelIndex = 0
+ TabStop = True
Text = "Min. Stage Allowed:"
TextAlign = 0
TextColor = &c00000000
TextFont = "System"
TextSize = 0.0
TextUnit = 0
- Top = 191
+ Top = 382
Transparent = False
Underline = False
Visible = True
@@ -337,15 +345,16 @@ Begin Window Window1
Multiline = False
Scope = 0
Selectable = False
- TabIndex = 9
+ TabIndex = 18
TabPanelIndex = 0
+ TabStop = True
Text = "Version"
TextAlign = 2
TextColor = &c00000000
TextFont = "SmallSystem"
TextSize = 0.0
TextUnit = 0
- Top = 359
+ Top = 543
Transparent = False
Underline = False
Visible = True
@@ -371,13 +380,14 @@ Begin Window Window1
LockTop = True
Scope = 0
State = 1
- TabIndex = 10
+ TabIndex = 9
TabPanelIndex = 0
TabStop = True
TextFont = "System"
TextSize = 0.0
TextUnit = 0
- Top = 149
+ Top = 280
+ Transparent = True
Underline = False
Value = True
Visible = True
@@ -403,13 +413,14 @@ Begin Window Window1
LockRight = False
LockTop = True
Scope = 0
- TabIndex = 11
+ TabIndex = 13
TabPanelIndex = 0
TabStop = True
TextFont = "System"
TextSize = 0.0
TextUnit = 0
- Top = 222
+ Top = 405
+ Transparent = True
Underline = False
Visible = True
Width = 171
@@ -434,20 +445,281 @@ Begin Window Window1
Multiline = False
Scope = 0
Selectable = False
- TabIndex = 12
+ TabIndex = 14
TabPanelIndex = 0
+ TabStop = True
Text = "Update File URL:"
TextAlign = 0
TextColor = &c00000000
TextFont = "System"
TextSize = 0.0
TextUnit = 0
- Top = 232
+ Top = 415
Transparent = False
Underline = False
Visible = True
Width = 152
End
+ Begin CheckBox cbAsynchrous
+ AutoDeactivate = True
+ Bold = False
+ Caption = "Asynchronous"
+ DataField = ""
+ DataSource = ""
+ Enabled = True
+ Height = 27
+ HelpTag = ""
+ Index = -2147483648
+ InitialParent = ""
+ Italic = False
+ Left = 20
+ LockBottom = False
+ LockedInPosition= False
+ LockLeft = True
+ LockRight = False
+ LockTop = True
+ Scope = 0
+ State = 1
+ TabIndex = 17
+ TabPanelIndex = 0
+ TabStop = True
+ TextFont = "System"
+ TextSize = 0.0
+ TextUnit = 0
+ Top = 504
+ Transparent = False
+ Underline = False
+ Value = True
+ Visible = True
+ Width = 159
+ End
+ Begin CheckBox cbUseAuthenticated
+ AutoDeactivate = True
+ Bold = False
+ Caption = "Authenticated"
+ DataField = ""
+ DataSource = ""
+ Enabled = True
+ Height = 20
+ HelpTag = ""
+ Index = -2147483648
+ InitialParent = ""
+ Italic = False
+ Left = 20
+ LockBottom = False
+ LockedInPosition= False
+ LockLeft = True
+ LockRight = False
+ LockTop = True
+ Scope = 0
+ State = 1
+ TabIndex = 10
+ TabPanelIndex = 0
+ TabStop = True
+ TextFont = "System"
+ TextSize = 0.0
+ TextUnit = 0
+ Top = 312
+ Transparent = True
+ Underline = False
+ Value = True
+ Visible = True
+ Width = 183
+ End
+ Begin TextField fldURL
+ AcceptTabs = False
+ Alignment = 0
+ AutoDeactivate = True
+ AutomaticallyCheckSpelling= False
+ BackColor = &cFFFFFF00
+ Bold = False
+ Border = True
+ CueText = "Fully formed url starting with http and including un:pw if required"
+ DataField = ""
+ DataSource = ""
+ Enabled = True
+ Format = ""
+ Height = 22
+ HelpTag = ""
+ Index = -2147483648
+ Italic = False
+ Left = 131
+ LimitText = 0
+ LockBottom = False
+ LockedInPosition= False
+ LockLeft = True
+ LockRight = False
+ LockTop = True
+ Mask = ""
+ Password = False
+ ReadOnly = False
+ Scope = 0
+ TabIndex = 2
+ TabPanelIndex = 0
+ TabStop = True
+ Text = ""
+ TextColor = &c00000000
+ TextFont = "System"
+ TextSize = 0.0
+ TextUnit = 0
+ Top = 96
+ Transparent = False
+ Underline = False
+ UseFocusRing = True
+ Visible = True
+ Width = 436
+ End
+ Begin Label Label1
+ AutoDeactivate = True
+ Bold = False
+ DataField = ""
+ DataSource = ""
+ Enabled = True
+ Height = 20
+ HelpTag = ""
+ Index = 3
+ InitialParent = ""
+ Italic = False
+ Left = 20
+ LockBottom = False
+ LockedInPosition= False
+ LockLeft = True
+ LockRight = False
+ LockTop = True
+ Multiline = False
+ Scope = 0
+ Selectable = False
+ TabIndex = 1
+ TabPanelIndex = 0
+ TabStop = True
+ Text = "Override URL:"
+ TextAlign = 0
+ TextColor = &c00000000
+ TextFont = "System"
+ TextSize = 0.0
+ TextUnit = 0
+ Top = 97
+ Transparent = False
+ Underline = False
+ Visible = True
+ Width = 112
+ End
+ Begin Label Label1
+ AutoDeactivate = True
+ Bold = False
+ DataField = ""
+ DataSource = ""
+ Enabled = True
+ Height = 74
+ HelpTag = ""
+ Index = 4
+ InitialParent = ""
+ Italic = False
+ Left = 20
+ LockBottom = False
+ LockedInPosition= False
+ LockLeft = True
+ LockRight = False
+ LockTop = True
+ Multiline = True
+ Scope = 0
+ Selectable = False
+ TabIndex = 3
+ TabPanelIndex = 0
+ TabStop = True
+ Text = "Override Public Key:"
+ TextAlign = 0
+ TextColor = &c00000000
+ TextFont = "System"
+ TextSize = 0.0
+ TextUnit = 0
+ Top = 130
+ Transparent = False
+ Underline = False
+ Visible = True
+ Width = 112
+ End
+ Begin TextArea fldPublicKey
+ AcceptTabs = False
+ Alignment = 0
+ AutoDeactivate = True
+ AutomaticallyCheckSpelling= True
+ BackColor = &cFFFFFF00
+ Bold = False
+ Border = True
+ DataField = ""
+ DataSource = ""
+ Enabled = True
+ Format = ""
+ Height = 74
+ HelpTag = "The public key that matches the file you are testing"
+ HideSelection = True
+ Index = -2147483648
+ Italic = False
+ Left = 131
+ LimitText = 0
+ LineHeight = 0.0
+ LineSpacing = 1.0
+ LockBottom = False
+ LockedInPosition= False
+ LockLeft = True
+ LockRight = False
+ LockTop = True
+ Mask = ""
+ Multiline = True
+ ReadOnly = False
+ Scope = 0
+ ScrollbarHorizontal= False
+ ScrollbarVertical= True
+ Styled = False
+ TabIndex = 4
+ TabPanelIndex = 0
+ TabStop = True
+ Text = ""
+ TextColor = &c00000000
+ TextFont = "SmallSystem"
+ TextSize = 0.0
+ TextUnit = 0
+ Top = 130
+ Transparent = False
+ Underline = False
+ UseFocusRing = True
+ Visible = True
+ Width = 436
+ End
+ Begin CheckBox cbAllowRedirection
+ AutoDeactivate = True
+ Bold = False
+ Caption = "Allow Redirection"
+ DataField = ""
+ DataSource = ""
+ Enabled = True
+ Height = 20
+ HelpTag = ""
+ Index = -2147483648
+ InitialParent = ""
+ Italic = False
+ Left = 20
+ LockBottom = False
+ LockedInPosition= False
+ LockLeft = True
+ LockRight = False
+ LockTop = True
+ Scope = 0
+ State = 1
+ TabIndex = 19
+ TabPanelIndex = 0
+ TabStop = True
+ TextFont = "System"
+ TextSize = 0.0
+ TextUnit = 0
+ Top = 344
+ Transparent = True
+ Underline = False
+ Value = True
+ Visible = True
+ Width = 183
+ End
End
#tag EndWindow
@@ -455,13 +727,21 @@ End
#tag Event
Sub Open()
dim u as new Kaju.UpdateChecker( App.PrefFolder )
- u.ServerPublicRSAKey = _
- "30820120300D06092A864886F70D01010105000382010D00308201080282010100D1DE526C8D98CCBFFDB4BD71487AC16205CF851696FB2910ABBC564BFEC1261A53A90794102BCC80EFB3CED3F8E73D90FF4C426D2315DE5E31A1A6C7563A21EADBD91B1DD637FAE0BED539C186BCB81DD865CC2A2F9427F717AA5E837C53AB90691569FC45EE17AF0ACD80E0C24C864EE86D4DBB7A6010E09B4E0BC556004E02980388C654A1C676A31E3AF788754E0CF7DEEC8236D55EDD5BB7490011B27CDEE5E254099FDE98C17D5F85014622D64C3BFB6A77200050FB2C8DF9A1ACEE50CF5A8353CE68304F91EC4F463E76BCF90A15152D03308B229FFE91E4906990D0E5F2E5C3ACC106E58DB1A37095DCBD5E233D7ED4A41AA263A73C54D4F12A113881020111"
u.DefaultImage = Some_Image
u.DefaultUseTransparency = true
Checker = u
+ AddHandler Checker.ExecuteAsyncComplete, WeakAddressOf Checker_ExecuteAsyncComplete
+
+ //
+ // Normally, this object will not be placed on a window, instead
+ // called directly in the App or similar. With that in mind,
+ // I opted for AddHandler here to simulate that rather than taking
+ // the easier course of placing the UpdateChecker into the window
+ // as a control.
+ //
+
End Sub
#tag EndEvent
@@ -474,6 +754,61 @@ End
End Sub
#tag EndMethod
+ #tag Method, Flags = &h21
+ Private Sub Checker_ExecuteAsyncComplete(sender As Kaju.UpdateChecker)
+ #pragma unused sender
+ HandlePostCheck
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h21
+ Private Sub HandlePostCheck()
+ select case Checker.Result
+ case Kaju.UpdateChecker.ResultType.UpdateAlreadyInProgress
+ lblResult.Text = "Update already in progress"
+
+ case Kaju.UpdateChecker.ResultType.UnsupportedOS
+ lblResult.Text = "This OS is not supported (missing required tools)"
+
+ case Kaju.UpdateChecker.ResultType.NoWritePermission
+ lblResult.Text = "Aborted (no write permission)"
+
+ case Kaju.UpdateChecker.ResultType.Error
+ lblResult.Text = "Error, user chose to try later"
+
+ case Kaju.UpdateChecker.ResultType.IgnoredUpdateAvailable
+ lblResult.Text = "Updates available, but ignored"
+
+ case Kaju.UpdateChecker.ResultType.NoUpdateAvailable
+ lblResult.Text = "No updates available"
+
+ case Kaju.UpdateChecker.ResultType.UpdateAvailable
+ lblResult.Text = "Updates available"
+
+ case Kaju.UpdateChecker.ResultType.RequiredUpdateAvailable
+ lblResult.Text = "Required update available"
+
+ case Kaju.UpdateChecker.ResultType.FetchingUpdateInfo
+ lblResult.Text = "Fetching update information"
+
+ case Kaju.UpdateChecker.ResultType.PageRedirected
+ lblResult.Text = "The URL was redirected to another page"
+
+ case Kaju.UpdateChecker.ResultType.PageNotFound
+ lblResult.Text = "The URL resulted in a 404 error"
+
+ else
+ lblResult.Text = "UNKNOWN RESULT"
+
+ end select
+
+ if Checker isa object and Checker.UpdateURL <> "" then
+ lblResult.Text = lblResult.Text + EndOfLine + EndOfLine + Checker.UpdateURL
+ end if
+
+ End Sub
+ #tag EndMethod
+
#tag Property, Flags = &h0
Checker As Kaju.UpdateChecker
@@ -483,6 +818,12 @@ End
#tag Constant, Name = kBaseURL, Type = String, Dynamic = False, Default = \"http://www.mactechnologies.com/Kaju_Test/", Scope = Public
#tag EndConstant
+ #tag Constant, Name = kBaseURLAuthenticated, Type = String, Dynamic = False, Default = \"http://Kaju:password@www.mactechnologies.com/Kaju_Test_Authenticated/", Scope = Public
+ #tag EndConstant
+
+ #tag Constant, Name = kServerPublicKey, Type = String, Dynamic = False, Default = \"30820120300D06092A864886F70D01010105000382010D00308201080282010100D1DE526C8D98CCBFFDB4BD71487AC16205CF851696FB2910ABBC564BFEC1261A53A90794102BCC80EFB3CED3F8E73D90FF4C426D2315DE5E31A1A6C7563A21EADBD91B1DD637FAE0BED539C186BCB81DD865CC2A2F9427F717AA5E837C53AB90691569FC45EE17AF0ACD80E0C24C864EE86D4DBB7A6010E09B4E0BC556004E02980388C654A1C676A31E3AF788754E0CF7DEEC8236D55EDD5BB7490011B27CDEE5E254099FDE98C17D5F85014622D64C3BFB6A77200050FB2C8DF9A1ACEE50CF5A8353CE68304F91EC4F463E76BCF90A15152D03308B229FFE91E4906990D0E5F2E5C3ACC106E58DB1A37095DCBD5E233D7ED4A41AA263A73C54D4F12A113881020111", Scope = Private
+ #tag EndConstant
+
#tag Constant, Name = kUpdateFile32bit, Type = String, Dynamic = False, Default = \"UpdateInformation32bit.html", Scope = Public
#tag EndConstant
@@ -498,9 +839,23 @@ End
#tag Events btnExecute
#tag Event
Sub Action()
+ dim baseURL as string = _
+ if( cbUseAuthenticated.Value, kBaseURLAuthenticated, kBaseURL )
+
Checker.HonorIgnored = cbHonorIgnored.Value
Checker.Allow32bitTo64bitUpdates = cbAllow32bitTo64bitUpdates.Value
- Checker.UpdateURL = pumChooseUpdateURL.RowTag( pumChooseUpdateURL.ListIndex )
+ dim url as string = fldURL.Text.Trim
+ if url = "" then
+ url = baseURL + pumChooseUpdateURL.RowTag( pumChooseUpdateURL.ListIndex ).StringValue
+ end if
+ Checker.UpdateURL = url
+ Checker.AllowRedirection = cbAllowRedirection.Value
+
+ dim pubKey as string = fldPublicKey.Text.Trim
+ if pubKey = "" then
+ pubKey = kServerPublicKey
+ end if
+ Checker.ServerPublicRSAKey = pubKey
dim allowWindow as integer = if( cbAllowWindow.Value, Kaju.UpdateChecker.kAllowUpdateWindow, 0 )
dim allowErrorDialog as integer = if( cbAllowErrorDialog.Value, Kaju.UpdateChecker.kAllowErrorDialog, 0 )
@@ -508,36 +863,16 @@ End
Checker.AllowedStage = pumStageAllowed.RowTag( pumStageAllowed.ListIndex )
- Checker.Execute()
-
- select case Checker.Result
- case Kaju.UpdateChecker.ResultType.UpdateAlreadyInProgress
- lblResult.Text = "Update already in progress"
-
- case Kaju.UpdateChecker.ResultType.UnsupportedOS
- lblResult.Text = "This OS is not supported (missing required tools)"
-
- case Kaju.UpdateChecker.ResultType.NoWritePermission
- lblResult.Text = "Aborted (no write permission)"
-
- case Kaju.UpdateChecker.ResultType.Error
- lblResult.Text = "Error, user chose to try later"
-
- case Kaju.UpdateChecker.ResultType.IgnoredUpdateAvailable
- lblResult.Text = "Updates available, but ignored"
-
- case Kaju.UpdateChecker.ResultType.NoUpdateAvailable
- lblResult.Text = "No updates available"
-
- case Kaju.UpdateChecker.ResultType.UpdateAvailable
- lblResult.Text = "Updates available"
-
- case Kaju.UpdateChecker.ResultType.RequiredUpdateAvailable
- lblResult.Text = "Required update available"
-
+ if cbAsynchrous.Value then
+ Checker.ExecuteAsync()
+ //
+ // See AddHandler notes in the Open event
+ //
else
- lblResult.Text = "UNKNOWN RESULT"
- end
+ Checker.Execute()
+ end if
+
+ HandlePostCheck
return
End Sub
@@ -579,50 +914,76 @@ End
#tag Events pumChooseUpdateURL
#tag Event
Sub Open()
- AddRowAndTag me, "All Updates", kBaseURL + kUpdateFileAll
- AddRowAndTag me, "32-bit Only", kBaseURL + kUpdateFile32bit
- AddRowAndTag me, "64-bit Only", kBaseURL + kUpdateFile64bit
+ AddRowAndTag me, "All Updates", kUpdateFileAll
+ AddRowAndTag me, "32-bit Only", kUpdateFile32bit
+ AddRowAndTag me, "64-bit Only", kUpdateFile64bit
me.ListIndex = 0
End Sub
#tag EndEvent
#tag EndEvents
+#tag Events fldURL
+ #tag Event
+ Sub TextChange()
+ if me.Text.Trim = "" then
+ cbUseAuthenticated.Enabled = true
+ else
+ cbUseAuthenticated.Enabled = false
+ end if
+ End Sub
+ #tag EndEvent
+#tag EndEvents
+#tag Events fldPublicKey
+ #tag Event
+ Sub TextChange()
+ dim newText as string = ReplaceLineEndings( me.Text, "" )
+ if newText <> me.Text then
+ me.Text = newText
+ end if
+
+ End Sub
+ #tag EndEvent
+#tag EndEvents
#tag ViewBehavior
#tag ViewProperty
- Name="BackColor"
+ Name="MinimumWidth"
Visible=true
- Group="Appearance"
- InitialValue="&hFFFFFF"
- Type="Color"
+ Group="Size"
+ InitialValue="64"
+ Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="Backdrop"
+ Name="MinimumHeight"
Visible=true
- Group="Appearance"
- Type="Picture"
- EditorType="Picture"
+ Group="Size"
+ InitialValue="64"
+ Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="CloseButton"
+ Name="MaximumWidth"
Visible=true
- Group="Appearance"
- InitialValue="True"
- Type="Boolean"
- EditorType="Boolean"
+ Group="Size"
+ InitialValue="32000"
+ Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="Composite"
- Group="Appearance"
- InitialValue="False"
- Type="Boolean"
+ Name="MaximumHeight"
+ Visible=true
+ Group="Size"
+ InitialValue="32000"
+ Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="Frame"
+ Name="Type"
Visible=true
- Group="Appearance"
+ Group="Frame"
InitialValue="0"
- Type="Integer"
+ Type="Types"
EditorType="Enum"
#tag EnumValues
"0 - Document"
@@ -639,142 +1000,147 @@ End
#tag EndEnumValues
#tag EndViewProperty
#tag ViewProperty
- Name="FullScreen"
- Group="Appearance"
- InitialValue="False"
+ Name="HasCloseButton"
+ Visible=true
+ Group="Frame"
+ InitialValue="True"
Type="Boolean"
- EditorType="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="FullScreenButton"
+ Name="HasMaximizeButton"
Visible=true
- Group="Appearance"
- InitialValue="False"
+ Group="Frame"
+ InitialValue="True"
Type="Boolean"
- EditorType="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="HasBackColor"
+ Name="HasMinimizeButton"
Visible=true
- Group="Appearance"
+ Group="Frame"
+ InitialValue="True"
+ Type="Boolean"
+ EditorType=""
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="HasFullScreenButton"
+ Visible=true
+ Group="Frame"
InitialValue="False"
Type="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="Height"
+ Name="DefaultLocation"
Visible=true
- Group="Position"
- InitialValue="400"
- Type="Integer"
+ Group="Behavior"
+ InitialValue="0"
+ Type="Locations"
+ EditorType="Enum"
+ #tag EnumValues
+ "0 - Default"
+ "1 - Parent Window"
+ "2 - Main Screen"
+ "3 - Parent Window Screen"
+ "4 - Stagger"
+ #tag EndEnumValues
#tag EndViewProperty
#tag ViewProperty
- Name="ImplicitInstance"
+ Name="HasBackgroundColor"
Visible=true
- Group="Appearance"
- InitialValue="True"
+ Group="Background"
+ InitialValue="False"
Type="Boolean"
- EditorType="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="Interfaces"
+ Name="BackgroundColor"
Visible=true
- Group="ID"
- Type="String"
- EditorType="String"
+ Group="Background"
+ InitialValue="&hFFFFFF"
+ Type="Color"
+ EditorType="Color"
#tag EndViewProperty
#tag ViewProperty
- Name="LiveResize"
+ Name="Backdrop"
Visible=true
Group="Appearance"
- InitialValue="True"
+ InitialValue=""
+ Type="Picture"
+ EditorType=""
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Composite"
+ Visible=false
+ Group="Appearance"
+ InitialValue="False"
Type="Boolean"
- EditorType="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="MacProcID"
+ Name="FullScreen"
+ Visible=false
Group="Appearance"
- InitialValue="0"
- Type="Integer"
+ InitialValue="False"
+ Type="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="MaxHeight"
+ Name="Height"
Visible=true
Group="Position"
- InitialValue="32000"
+ InitialValue="400"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="MaximizeButton"
+ Name="ImplicitInstance"
Visible=true
Group="Appearance"
InitialValue="True"
Type="Boolean"
- EditorType="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
- Name="MaxWidth"
+ Name="Interfaces"
Visible=true
- Group="Position"
- InitialValue="32000"
+ Group="ID"
+ InitialValue=""
+ Type="String"
+ EditorType=""
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="MacProcID"
+ Visible=false
+ Group="Appearance"
+ InitialValue="0"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="MenuBar"
Visible=true
Group="Appearance"
+ InitialValue=""
Type="MenuBar"
- EditorType="MenuBar"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="MenuBarVisible"
+ Visible=false
Group="Appearance"
InitialValue="True"
Type="Boolean"
- EditorType="Boolean"
- #tag EndViewProperty
- #tag ViewProperty
- Name="MinHeight"
- Visible=true
- Group="Position"
- InitialValue="64"
- Type="Integer"
- #tag EndViewProperty
- #tag ViewProperty
- Name="MinimizeButton"
- Visible=true
- Group="Appearance"
- InitialValue="True"
- Type="Boolean"
- EditorType="Boolean"
- #tag EndViewProperty
- #tag ViewProperty
- Name="MinWidth"
- Visible=true
- Group="Position"
- InitialValue="64"
- Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Name"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
- EditorType="String"
- #tag EndViewProperty
- #tag ViewProperty
- Name="Placement"
- Visible=true
- Group="Position"
- InitialValue="0"
- Type="Integer"
- EditorType="Enum"
- #tag EnumValues
- "0 - Default"
- "1 - Parent Window"
- "2 - Main Screen"
- "3 - Parent Window Screen"
- "4 - Stagger"
- #tag EndEnumValues
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Resizeable"
@@ -782,14 +1148,15 @@ End
Group="Appearance"
InitialValue="True"
Type="Boolean"
- EditorType="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Super"
Visible=true
Group="ID"
+ InitialValue=""
Type="String"
- EditorType="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Title"
@@ -797,6 +1164,7 @@ End
Group="Appearance"
InitialValue="Untitled"
Type="String"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Visible"
@@ -804,7 +1172,7 @@ End
Group="Appearance"
InitialValue="True"
Type="Boolean"
- EditorType="Boolean"
+ EditorType=""
#tag EndViewProperty
#tag ViewProperty
Name="Width"
@@ -812,5 +1180,6 @@ End
Group="Position"
InitialValue="600"
Type="Integer"
+ EditorType=""
#tag EndViewProperty
#tag EndViewBehavior
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 fe68338..8ffaa48 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_Linux_64.zip b/Update Test Files (Upload These)/Kaju_Update_Test_Linux_64.zip
index 39bc17d..563caf2 100644
Binary files a/Update Test Files (Upload These)/Kaju_Update_Test_Linux_64.zip and b/Update Test Files (Upload These)/Kaju_Update_Test_Linux_64.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 879eeed..c69ab56 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 108e69c..3654947 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)/Kaju_Update_Test_Win_64.zip b/Update Test Files (Upload These)/Kaju_Update_Test_Win_64.zip
index 4456c21..39342a1 100644
Binary files a/Update Test Files (Upload These)/Kaju_Update_Test_Win_64.zip and b/Update Test Files (Upload These)/Kaju_Update_Test_Win_64.zip differ
diff --git a/Update Test Files (Upload These)/UpdateInformation.html b/Update Test Files (Upload These)/UpdateInformation.html
index 4ee7ccb..939e7fd 100644
--- a/Update Test Files (Upload These)/UpdateInformation.html
+++ b/Update Test Files (Upload These)/UpdateInformation.html
@@ -1,166 +1,176 @@
-KAJU D0BF3461CB70901D7630808C2E4F4E5EFF26D24D9FC929663A37FC3AB2F43E328D795CDAB089CE00FEDE6D88393DC6159AED79BF70DD02C1AD354DC1EBC56843AD354E3ADE40DB7A96326020FD389A7B1C52FD81EFAA1EFDE84922221F3E71EDEB82C74F63D67C235023E47E2B23F7893D151C27CA7B6833E8072D3E11F5679F0EBEB2B4457751EB43591F964C2AA3CFF711B226E350A4CB0778611552A8860526D17C0341DC7CBDDCCA2A619AA5B539CE653FEDDADDA64436500D7ABB16C2643E7E2F71CF233D828E445D6B84D4BA8652AABD3135727E71A5119DB3CA55A9E76213248A2025F38F5E8C8BA054E0D585CAA0C4B8E6FEC1DDFD6A26EF0CE56B1C
+KAJU 9E368490B29236933B69A92E7C834C3CC514C7B2FB708C1D2E15EB5D8EFB46EF0A0B53F4FC5CF3DB56B27B1884692ADDD47D439BDF06FEE2114263EDD8A483E21939C0C786478CBD956E800688E1B456F1853B9DD78AFF436998E7D66FF1E4EB2F646CB369B981029D4CE65BB3D307D7827BF64A72980B031962F253E11268DD8A0B242BBD03319EAED4BF4D23373559112E9887A66C4E103865DF40F81B88A7044D6F54618549B8D37A295A4605DC3F501AB4B40528CEDF415444F77CB9455D06F312DA1459D4DFF3C658D647138C960BB7D2282FAE01730924A540030CFAC307A043C45CA19EBE7EFF7D56FAD4D1BADB47C9CCE681FF9B525B12D1ACA19BAC
[
{
"AppName":"Kaju Update Test",
+ "ImageScale":1,
"ImageURL":"",
"MinimumRequiredVersion":"",
"ReleaseNotes":" This is a fake update for v.1.1 (10). It will really point to a binary of 1.0. (This demonstrates the use of the optional build number for final versions.) In other words, the app will replace itself. NOTE: The update will warn you that the update will require a payment. THIS IS A LIE!! It’s only set that way to test the “Requires Payment” option. A phony development version pointing to the same binary. Meant as a placeholder to demonstrate multiple versions. Note that this version has a name change. A phony development version pointing to the same binary. Meant as a placeholder to demonstrate multiple versions. Visit my web site! Note that this version has a name change. These are alternate release notes. If the URL above can’t be accessed or returns an empty string, this will be displayed instead. Try fiddling with the URL to see the results. A phony beta pointing to the same binary. Meant as a placeholder to demonstrate multiple versions. IMPORTANT: The URL’s for the binaries have been intentionally switched to test the hash function. Attempting to update to this version should result in an error.Changes<\/h3>\n
",
"RequiresPayment":false,
"UseTransparency":true,
"Version":"1.2b2",
+ "Security Token":"imdB+t/DcJ4=",
"MacBinary":{
- "Hash":"FAE717E57CDA429B80354D111A02F462",
+ "Hash":"5A66CD3648FC633C2CC3AC57FBB4CA80",
"URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Linux.zip"
},
"WindowsBinary":{
- "Hash":"3B03F9EB5303C7BBEA218B25C3D1A70C",
+ "Hash":"ECECC37A150B297CDB69EC32813136F6",
"URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Mac.zip",
"ExecutableName":"Kaju Update Test.exe"
},
"LinuxBinary":{
- "Hash":"12F76303CED60E293A3E33D80F682282",
+ "Hash":"A386E0321651CFA41C7544D91BB8AACE",
"URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Win.zip",
"ExecutableName":"Kaju Update Test"
},
"WindowsBinary64bit":{
- "Hash":"181779AD10242CB19EA36DBFA948C85D",
+ "Hash":"8225FE35A48D461638092DE9286A43DA",
"URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Linux_64.zip",
"ExecutableName":"Kaju Update Test.exe"
},
"LinuxBinary64bit":{
- "Hash":"273B9E735AB4C9E6A371159A759A0610",
+ "Hash":"864E7E6D1E48B0E09ADD1D8CC6F76C08",
"URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Win_64.zip",
"ExecutableName":"Kaju Update Test"
}
},
{
"AppName":"Kaju Update Test",
+ "ImageScale":1,
"ImageURL":"",
"MinimumRequiredVersion":"",
"ReleaseNotes":"\n
Changes
\n\n
",
"RequiresPayment":true,
"UseTransparency":false,
"Version":"1.1 (10)",
+ "Security Token":"bTrObWqxkJw=",
"MacBinary":{
- "Hash":"FAE717E57CDA429B80354D111A02F462",
+ "Hash":"5A66CD3648FC633C2CC3AC57FBB4CA80",
"URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Mac.zip"
},
"WindowsBinary":{
- "Hash":"3B03F9EB5303C7BBEA218B25C3D1A70C",
+ "Hash":"ECECC37A150B297CDB69EC32813136F6",
"URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Win.zip",
"ExecutableName":"Kaju Update Test.exe"
},
"LinuxBinary":{
- "Hash":"12F76303CED60E293A3E33D80F682282",
+ "Hash":"A386E0321651CFA41C7544D91BB8AACE",
"URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Linux.zip",
"ExecutableName":"Kaju Update Test"
},
"WindowsBinary64bit":{
- "Hash":"181779AD10242CB19EA36DBFA948C85D",
+ "Hash":"8225FE35A48D461638092DE9286A43DA",
"URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Win_64.zip",
"ExecutableName":"Kaju Update Test.exe"
},
"LinuxBinary64bit":{
- "Hash":"273B9E735AB4C9E6A371159A759A0610",
+ "Hash":"864E7E6D1E48B0E09ADD1D8CC6F76C08",
"URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Linux_64.zip",
"ExecutableName":"Kaju Update Test"
}
},
{
"AppName":"New Kaju Update Test",
+ "ImageScale":1,
"ImageURL":"",
"MinimumRequiredVersion":"",
- "ReleaseNotes":"
A fake release that should never appear. (Except in Preview.)
", "RequiresPayment":false, "UseTransparency":false, "Version":"0.9", + "Security Token":"AMORx31tniU=", "MacBinary":{ - "Hash":"FAE717E57CDA429B80354D111A02F462", + "Hash":"5A66CD3648FC633C2CC3AC57FBB4CA80", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Mac.zip" }, "WindowsBinary":{ - "Hash":"3B03F9EB5303C7BBEA218B25C3D1A70C", + "Hash":"ECECC37A150B297CDB69EC32813136F6", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Win.zip", "ExecutableName":"Kaju Update Test.exe" }, "LinuxBinary":{ - "Hash":"12F76303CED60E293A3E33D80F682282", + "Hash":"A386E0321651CFA41C7544D91BB8AACE", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Linux.zip", "ExecutableName":"Kaju Update Test" }, "WindowsBinary64bit":{ - "Hash":"181779AD10242CB19EA36DBFA948C85D", + "Hash":"8225FE35A48D461638092DE9286A43DA", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Win_64.zip", "ExecutableName":"Kaju Update Test.exe" }, "LinuxBinary64bit":{ - "Hash":"273B9E735AB4C9E6A371159A759A0610", + "Hash":"864E7E6D1E48B0E09ADD1D8CC6F76C08", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Linux_64.zip", "ExecutableName":"Kaju Update Test" } diff --git a/Update Test Files (Upload These)/UpdateInformation32bit.html b/Update Test Files (Upload These)/UpdateInformation32bit.html index 2b5e399..a2bbdf0 100644 --- a/Update Test Files (Upload These)/UpdateInformation32bit.html +++ b/Update Test Files (Upload These)/UpdateInformation32bit.html @@ -1,116 +1,126 @@ -KAJU 8F3778013CFEBF026C55DAC35A4198084BEB8403942FAA9F69CF98B23C2547B89F09ADBB16DCC9956C52A9D298F6C09B6AD46E2874BEADEC400261809A9D69322CE2C77467301F0D902021CEF874BD44917981F6A0FD9C9BF1FF44F735D0A0E881EA46A8D49C545E300C542DFA6B169BD31A8756AFD3AF76394D8066A6597CFF5B1803845F1D0FA422ACA871DB7E9B6669DCB63A0E7C67F05CD6763B91C6BABFC55A1C903234195137C36FE75B9F83C79ECDA733E07A7D1F6BAE8821A3ED52E664E4CC2A5E1AEEAD004B75C7EC42088E128B4BF49105BAB704D7175E6ED39B4980D280E6300527B736D9EC68BFCD7249B759AF262E0F3DF51214F89622A41CC5 +KAJU 5D780CB55DED1CC5F09AD357A281EF91BCFDDDB90B734E263B88C3B54AA8E04491085ACB1763863CBC4CA8C55E1F98F63130E012B2A78A2126BD762A94EB0470818564AB9CFDB7A64E2CE5F46D4187180A9FEDD9BF0107EC23EA35F7D62FF20AB9E465D138C966EDD4E6D61CFAE89B828BBA67D05702848BE07EF2B7F58052A6505A273335887A0C73E9B4C7D4B48457E0750772D17AA4DBAB9594B685121A6C14D4C558C6BD63E45BC6ADE7B1A3BB5E9E1E05247B99D7A7129B349DF448FA7F3709666E29B8BD18A2C6A0DFBE169CB42D58AF95CE15EEAE28AC98896F69CC4F4D6E2381421C75B10F93265FCD303115E62570114654ACC13120F75ED1BF6056 [ { "AppName":"Kaju Update Test", + "ImageScale":1, "ImageURL":"", "MinimumRequiredVersion":"", "ReleaseNotes":"This is a fake update for v.1.1 (10). It will really point to a binary of 1.0. (This demonstrates the use of the optional build number for final versions.)
\n\rIn other words, the app will replace itself.
\n\nNOTE: The update will warn you that the update will require a payment. THIS IS A LIE!! It’s only set that way to test the “Requires Payment” option.
\n\nA phony development version pointing to the same binary. Meant as a placeholder to demonstrate multiple versions.
\n\nNote that this version has a name change.
", + "ReleaseNotes":"A phony development version pointing to the same binary. Meant as a placeholder to demonstrate multiple versions.
\nVisit my web site!
\nNote that this version has a name change.
", "RequiresPayment":false, "UseTransparency":false, "Version":"1.2.2d5", + "Security Token":"Ck4xaZl6tKM=", "MacBinary":{ - "Hash":"FAE717E57CDA429B80354D111A02F462", + "Hash":"5A66CD3648FC633C2CC3AC57FBB4CA80", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Mac.zip" }, "WindowsBinary":{ - "Hash":"3B03F9EB5303C7BBEA218B25C3D1A70C", + "Hash":"ECECC37A150B297CDB69EC32813136F6", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Win.zip", "ExecutableName":"Kaju Update Test.exe" }, "LinuxBinary":{ - "Hash":"12F76303CED60E293A3E33D80F682282", + "Hash":"A386E0321651CFA41C7544D91BB8AACE", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Linux.zip", "ExecutableName":"Kaju Update Test" } }, { "AppName":"Kaju Update Test", + "ImageScale":1, "ImageURL":"", "MinimumRequiredVersion":"", "ReleaseNotes":"\n\n\n\nThese are alternate release notes. If the URL above can’t be accessed or returns an empty string, this will be displayed instead.
\n\nTry fiddling with the URL to see the results.
", "RequiresPayment":false, "UseTransparency":false, "Version":"1.2.1a4", + "Security Token":"Mc8KLloByME=", "MacBinary":{ - "Hash":"FAE717E57CDA429B80354D111A02F462", + "Hash":"5A66CD3648FC633C2CC3AC57FBB4CA80", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Mac.zip" }, "WindowsBinary":{ - "Hash":"3B03F9EB5303C7BBEA218B25C3D1A70C", + "Hash":"ECECC37A150B297CDB69EC32813136F6", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Win.zip", "ExecutableName":"Kaju Update Test.exe" }, "LinuxBinary":{ - "Hash":"12F76303CED60E293A3E33D80F682282", + "Hash":"A386E0321651CFA41C7544D91BB8AACE", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Linux.zip", "ExecutableName":"Kaju Update Test" } }, { "AppName":"Kaju Update Test", - "ImageURL":"http://www.mactechnologies.com/Kaju_Test/Some_Image_beta.png", + "ImageScale":2, + "ImageURL":"http://www.mactechnologies.com/Kaju_Test/plush-bears-beta@2x.png", "MinimumRequiredVersion":"", "ReleaseNotes":"A phony beta pointing to the same binary. Meant as a placeholder to demonstrate multiple versions.
\n\nIMPORTANT: The URL’s for the binaries have been intentionally switched to test the hash function. Attempting to update to this version should result in an error.", "RequiresPayment":false, "UseTransparency":true, "Version":"1.2b2", + "Security Token":"wuixea464fE=", "MacBinary":{ - "Hash":"FAE717E57CDA429B80354D111A02F462", + "Hash":"5A66CD3648FC633C2CC3AC57FBB4CA80", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Linux.zip" }, "WindowsBinary":{ - "Hash":"3B03F9EB5303C7BBEA218B25C3D1A70C", + "Hash":"ECECC37A150B297CDB69EC32813136F6", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Mac.zip", "ExecutableName":"Kaju Update Test.exe" }, "LinuxBinary":{ - "Hash":"12F76303CED60E293A3E33D80F682282", + "Hash":"A386E0321651CFA41C7544D91BB8AACE", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Win.zip", "ExecutableName":"Kaju Update Test" } }, { "AppName":"Kaju Update Test", + "ImageScale":1, "ImageURL":"", "MinimumRequiredVersion":"", "ReleaseNotes":"
A fake release that should never appear. (Except in Preview.)
", "RequiresPayment":false, "UseTransparency":false, "Version":"0.9", + "Security Token":"de2OA8/9Zn4=", "MacBinary":{ - "Hash":"FAE717E57CDA429B80354D111A02F462", + "Hash":"5A66CD3648FC633C2CC3AC57FBB4CA80", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Mac.zip" }, "WindowsBinary":{ - "Hash":"3B03F9EB5303C7BBEA218B25C3D1A70C", + "Hash":"ECECC37A150B297CDB69EC32813136F6", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Win.zip", "ExecutableName":"Kaju Update Test.exe" }, "LinuxBinary":{ - "Hash":"12F76303CED60E293A3E33D80F682282", + "Hash":"A386E0321651CFA41C7544D91BB8AACE", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Linux.zip", "ExecutableName":"Kaju Update Test" } diff --git a/Update Test Files (Upload These)/UpdateInformation64bit.html b/Update Test Files (Upload These)/UpdateInformation64bit.html index bb5f718..76c3840 100644 --- a/Update Test Files (Upload These)/UpdateInformation64bit.html +++ b/Update Test Files (Upload These)/UpdateInformation64bit.html @@ -1,116 +1,126 @@ -KAJU CBB91BE5A24E020F723381A2AB85DCD6127DE91B50FB40591404512DA8FF9DCB2D5FFA72BB727DF89BDCF33D086985C8862DCBDA57A0827BC9C761F103CCC88E6A4E2FD9EE4D77B3BF20671ABFC465138D34F79C4FB26D8746C58C6E1DAC8A87EBC59EEB4930A6A914CD91DC7DA8DFC0E59388FB2BEDB6D4489CA0F77FEF8CA53A8F3E982D3A5E8CD3991B26B31A9F80D90E595749901E0087915270F95DA0F4D38BD0A1A6DCAB84DFE0F61576018B1CFC15F1FA3889851949A7B744ECF5310B49346A2920E17541D6C8525EA21DE49B215351E8714D4EDD37A883ECD6E550F2493214D822F4CB70C7561A35AA97ABC181E9F4B62F0573B484825D654BFE8125 +KAJU 4434077A606E6F72A71F3E0B9C04A8DC17BEFBD67EFCA7C4BACC20F9C88D838A59083D5AF9D7944F1A5964BE22727887A1C1AF0539903C3CB17FB84A7ECE78A0399F547D56D532DEECF430479FECA4ABAF4C34213967031C53C35403AFF402C42CB0A2319E1CE114AC718717FF61D3A852D280745A8FCF8B27C81CDED6ED2DFEAABA571C8B801124C30DED899C200FBD364A4E1146B817BC86DFE3C2A7A9F3753875F44CC5BBE7E5B85371A6190079D1FAC1B93C231202A28EEA1576B338D5597B44AD51EEF974C33DAD16118CC95850FE2CA9444A1F50C21ED710A3F8D68069D59BE9DB70B5F551E6F57ABB4D20B1EC40E7610C2371C6CFAD17D49C9BAFFDCE [ { "AppName":"Kaju Update Test", + "ImageScale":1, "ImageURL":"", "MinimumRequiredVersion":"", "ReleaseNotes":"This is a fake update for v.1.1 (10). It will really point to a binary of 1.0. (This demonstrates the use of the optional build number for final versions.)
\n\rIn other words, the app will replace itself.
\n\nNOTE: The update will warn you that the update will require a payment. THIS IS A LIE!! It’s only set that way to test the “Requires Payment” option.
\n\nA phony development version pointing to the same binary. Meant as a placeholder to demonstrate multiple versions.
\n\nNote that this version has a name change.
", + "ReleaseNotes":"A phony development version pointing to the same binary. Meant as a placeholder to demonstrate multiple versions.
\nVisit my web site!
\nNote that this version has a name change.
", "RequiresPayment":false, "UseTransparency":false, "Version":"1.2.2d5", + "Security Token":"McYxhSgmp1I=", "MacBinary":{ - "Hash":"FAE717E57CDA429B80354D111A02F462", + "Hash":"5A66CD3648FC633C2CC3AC57FBB4CA80", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Mac.zip" }, "WindowsBinary64bit":{ - "Hash":"181779AD10242CB19EA36DBFA948C85D", + "Hash":"8225FE35A48D461638092DE9286A43DA", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Win_64.zip", "ExecutableName":"Kaju Update Test.exe" }, "LinuxBinary64bit":{ - "Hash":"273B9E735AB4C9E6A371159A759A0610", + "Hash":"864E7E6D1E48B0E09ADD1D8CC6F76C08", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Linux_64.zip", "ExecutableName":"Kaju Update Test" } }, { "AppName":"Kaju Update Test", + "ImageScale":1, "ImageURL":"", "MinimumRequiredVersion":"", "ReleaseNotes":"\n\n\n\nThese are alternate release notes. If the URL above can’t be accessed or returns an empty string, this will be displayed instead.
\n\nTry fiddling with the URL to see the results.
", "RequiresPayment":false, "UseTransparency":false, "Version":"1.2.1a4", + "Security Token":"lQGD2NrrXWc=", "MacBinary":{ - "Hash":"FAE717E57CDA429B80354D111A02F462", + "Hash":"5A66CD3648FC633C2CC3AC57FBB4CA80", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Mac.zip" }, "WindowsBinary64bit":{ - "Hash":"181779AD10242CB19EA36DBFA948C85D", + "Hash":"8225FE35A48D461638092DE9286A43DA", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Win_64.zip", "ExecutableName":"Kaju Update Test.exe" }, "LinuxBinary64bit":{ - "Hash":"273B9E735AB4C9E6A371159A759A0610", + "Hash":"864E7E6D1E48B0E09ADD1D8CC6F76C08", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Linux_64.zip", "ExecutableName":"Kaju Update Test" } }, { "AppName":"Kaju Update Test", - "ImageURL":"http://www.mactechnologies.com/Kaju_Test/Some_Image_beta.png", + "ImageScale":2, + "ImageURL":"http://www.mactechnologies.com/Kaju_Test/plush-bears-beta@2x.png", "MinimumRequiredVersion":"", "ReleaseNotes":"A phony beta pointing to the same binary. Meant as a placeholder to demonstrate multiple versions.
\n\nIMPORTANT: The URL’s for the binaries have been intentionally switched to test the hash function. Attempting to update to this version should result in an error.", "RequiresPayment":false, "UseTransparency":true, "Version":"1.2b2", + "Security Token":"NVrNOtLyYVk=", "MacBinary":{ - "Hash":"FAE717E57CDA429B80354D111A02F462", + "Hash":"5A66CD3648FC633C2CC3AC57FBB4CA80", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Linux.zip" }, "WindowsBinary64bit":{ - "Hash":"181779AD10242CB19EA36DBFA948C85D", + "Hash":"8225FE35A48D461638092DE9286A43DA", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Linux_64.zip", "ExecutableName":"Kaju Update Test.exe" }, "LinuxBinary64bit":{ - "Hash":"273B9E735AB4C9E6A371159A759A0610", + "Hash":"864E7E6D1E48B0E09ADD1D8CC6F76C08", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Win_64.zip", "ExecutableName":"Kaju Update Test" } }, { "AppName":"Kaju Update Test", + "ImageScale":1, "ImageURL":"", "MinimumRequiredVersion":"", "ReleaseNotes":"
A fake release that should never appear. (Except in Preview.)
", "RequiresPayment":false, "UseTransparency":false, "Version":"0.9", + "Security Token":"d5Sv4F3G7zE=", "MacBinary":{ - "Hash":"FAE717E57CDA429B80354D111A02F462", + "Hash":"5A66CD3648FC633C2CC3AC57FBB4CA80", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Mac.zip" }, "WindowsBinary64bit":{ - "Hash":"181779AD10242CB19EA36DBFA948C85D", + "Hash":"8225FE35A48D461638092DE9286A43DA", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Win_64.zip", "ExecutableName":"Kaju Update Test.exe" }, "LinuxBinary64bit":{ - "Hash":"273B9E735AB4C9E6A371159A759A0610", + "Hash":"864E7E6D1E48B0E09ADD1D8CC6F76C08", "URL":"http://www.mactechnologies.com/Kaju_Test/Kaju_Update_Test_Linux_64.zip", "ExecutableName":"Kaju Update Test" } diff --git a/Update Test Files (Upload These)/plush-bears-beta@2x.png b/Update Test Files (Upload These)/plush-bears-beta@2x.png new file mode 100644 index 0000000..94f4a90 Binary files /dev/null and b/Update Test Files (Upload These)/plush-bears-beta@2x.png differ