-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
83f74f7
commit 79cc52e
Showing
3 changed files
with
213 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
using Microsoft.Extensions.Configuration; | ||
using System; | ||
using System.IO; | ||
using Newtonsoft.Json; | ||
using Newtonsoft.Json.Linq; | ||
|
||
namespace VSCodeRecoveryTool | ||
{ | ||
internal class Program | ||
{ | ||
static void Main(string[] args) | ||
{ | ||
Restore restore = new Restore(); | ||
restore.Run(); | ||
} | ||
} | ||
public class Entry | ||
{ | ||
public String? id { get; set; } | ||
public Int64? timestamp { get; set; } | ||
} | ||
|
||
public class JSONFileRoot | ||
{ | ||
public Int32? version { get; set; } | ||
public String? resource { get; set; } | ||
public List<Entry>? entries { get; set; } | ||
} | ||
|
||
public class Restore | ||
{ | ||
public void cw(String? text) | ||
{ | ||
Console.WriteLine(text); | ||
} | ||
|
||
public void Run() | ||
{ | ||
var configurationBuilder = new ConfigurationBuilder() | ||
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); | ||
IConfiguration configuration = configurationBuilder.Build(); | ||
String? VSCodeHistoryDirectory = configuration["AppSettings:VSCodeHistoryDirectory"]; | ||
String? VSCodeRecoveryDirectory = configuration["AppSettings:VSCodeRecoveryDirectory"]; | ||
|
||
if (VSCodeRecoveryDirectory != null) | ||
{ | ||
try | ||
{ | ||
if (Directory.Exists(VSCodeRecoveryDirectory)) | ||
{ | ||
// Uncomment the Directory.Delete and the Directory.CreateDirectory lines to allow recovery directory to be fully refreshed - make sure to configure appsettings.json correctly first | ||
// Directory.Delete(VSCodeRecoveryDirectory, true); | ||
} | ||
// Directory.CreateDirectory(VSCodeRecoveryDirectory); | ||
|
||
if (VSCodeHistoryDirectory != null) | ||
{ | ||
var vsCodeHistoryDirectoryInfo = new DirectoryInfo(VSCodeHistoryDirectory); | ||
var vsCodeHistoryDirectories = vsCodeHistoryDirectoryInfo.EnumerateDirectories() | ||
.OrderBy(d => d.LastWriteTime) | ||
.Select(d => d.Name) | ||
.ToList(); | ||
|
||
foreach (var snapshotDirectory in vsCodeHistoryDirectories) | ||
{ | ||
cw(snapshotDirectory); | ||
String snapshotDirectoryFullPath = VSCodeHistoryDirectory + "/" + snapshotDirectory; | ||
var snapshotDirectoryInfo = new DirectoryInfo(snapshotDirectoryFullPath); | ||
|
||
var snapshotFiles = snapshotDirectoryInfo.EnumerateFiles() | ||
.OrderBy(f => f.LastWriteTime) | ||
.Select(f => f.Name) | ||
.ToList(); | ||
|
||
Int32 fileCount = 0; | ||
JSONFileRoot? entriesJSONFile; | ||
|
||
foreach (var snapshotFile in snapshotFiles) | ||
{ | ||
fileCount+=1; | ||
var snapshotFileInfo = new FileInfo(snapshotFile); | ||
|
||
if (fileCount == 1) | ||
{ | ||
//export the latest file | ||
var jsonFile = snapshotDirectoryFullPath + "/entries.json"; | ||
String? originalFilePath = ""; | ||
|
||
using (StreamReader reader = new StreamReader(jsonFile)) | ||
{ | ||
String jsonFileString = reader.ReadToEnd(); | ||
if (jsonFileString != null) | ||
{ | ||
entriesJSONFile = JsonConvert.DeserializeObject<JSONFileRoot>(jsonFileString); | ||
if (entriesJSONFile != null && entriesJSONFile.entries != null) | ||
{ | ||
List<Entry>? entries = entriesJSONFile.entries; | ||
String? resource = entriesJSONFile.resource; | ||
if (resource != null) { originalFilePath = resource.Replace("file://",""); } | ||
String? fileId = ""; | ||
String? fileTimestamp = ""; | ||
String? snapshotFileFullPath = ""; | ||
String? restoreToFilePath = ""; | ||
String? dirCheckString = ""; | ||
String? originalFileName = ""; | ||
String? restoreToFullPath = ""; | ||
|
||
if (entries != null) | ||
{ | ||
Int32 i = 0; | ||
List<Entry>? entriesOrderedByDateDescList = entries.OrderByDescending(x => x.timestamp).ToList(); | ||
foreach (Entry? orderedEntry in entriesOrderedByDateDescList) | ||
{ | ||
restoreToFilePath = ""; | ||
snapshotFileFullPath = ""; | ||
if (orderedEntry != null && orderedEntry.timestamp != null) | ||
{ | ||
if (i == 0) //get first in descending by date list to restore latest file | ||
{ | ||
restoreToFilePath = VSCodeRecoveryDirectory + originalFilePath; | ||
fileId = orderedEntry.id; | ||
fileTimestamp = orderedEntry.timestamp.ToString(); | ||
originalFileName = ""; | ||
restoreToFullPath = ""; | ||
|
||
//restore original file to full path | ||
snapshotFileFullPath = snapshotDirectoryFullPath + "/" + fileId; | ||
|
||
String[] restorePathArray = restoreToFilePath.Split('/'); | ||
originalFileName = restorePathArray[restorePathArray.Length - 1]; | ||
|
||
Int32 j = 0; | ||
foreach (var dir in restorePathArray) | ||
{ | ||
if (dir != "") | ||
{ | ||
if (j == restorePathArray.Length - 1) //end of path array or filename | ||
{ | ||
restoreToFullPath = dirCheckString + "/" + dir; | ||
if (File.Exists(restoreToFullPath)) | ||
{ | ||
// Uncomment the File.Delete and the File.Copy lines to allow recovery directory to be fully refreshed - make sure to configure appsettings.json correctly first | ||
// File.Delete(restoreToFullPath); | ||
} | ||
// File.Copy(snapshotFileFullPath, restoreToFullPath); | ||
} | ||
else | ||
{ | ||
dirCheckString += "/" + dir; | ||
if (!Directory.Exists(dirCheckString)) | ||
{ | ||
Directory.CreateDirectory(dirCheckString); | ||
} | ||
} | ||
} | ||
j+=1; | ||
} | ||
} | ||
} | ||
i+=1; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
} | ||
catch (IOException ioex) | ||
{ | ||
cw("IO exception : " + ioex.Message + "\nMake sure appsettings.json is configured correctly."); | ||
} | ||
catch (Exception ex) | ||
{ | ||
cw("Exception : " + ex.Message); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net7.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" /> | ||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" /> | ||
<None Update="appsettings.json"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"AppSettings": { | ||
"AppName": "VSCodeRecoveryTool", | ||
"AppVersion": "1.0.1", | ||
"VSCodeHistoryDirectory": "/home/<user>/.config/Code/User/History", | ||
"VSCodeRecoveryDirectory": "/home/<user>/.config/Code/User/Recovery" | ||
} | ||
} |