Created
June 1, 2016 20:36
-
-
Save espresso3389/6c0e0ebcea8c2d7f07b8e2542b6e5e16 to your computer and use it in GitHub Desktop.
Chrome Cache Retriever
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
using System; | |
using System.Drawing; | |
using System.Drawing.Imaging; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Runtime.InteropServices; | |
namespace cie | |
{ | |
public delegate void WriteLineDelegate(string format, params object[] args); | |
public class ChromeImageExtractor : IDisposable | |
{ | |
public ChromeImageExtractor() | |
{ | |
init(null); | |
} | |
public ChromeImageExtractor(string outDir) | |
{ | |
init(outDir); | |
} | |
void init(string outDir) | |
{ | |
string appData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); | |
_cachePath = Path.Combine(appData, @"Google\Chrome\User Data\Default\Cache"); | |
if (string.IsNullOrEmpty(outDir)) | |
outDir = Path.Combine(Environment.CurrentDirectory, "output"); | |
_outDir = outDir; | |
} | |
public void Dispose() | |
{ | |
StopWatch(); | |
GC.SuppressFinalize(this); | |
} | |
public void StartWatch() | |
{ | |
writeLine("Watching incoming files..."); | |
_fsysWatcher = new FileSystemWatcher(); | |
_fsysWatcher.Path = _cachePath; | |
_fsysWatcher.IncludeSubdirectories = true; | |
_fsysWatcher.Filter = "*"; | |
_fsysWatcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.FileName; | |
_fsysWatcher.Created += OnFileNotify; | |
_fsysWatcher.Changed += OnFileNotify; | |
_fsysWatcher.Renamed += OnFileNotify; | |
_fsysWatcher.EnableRaisingEvents = true; | |
} | |
public void StopWatch() | |
{ | |
try | |
{ | |
if (_fsysWatcher != null) | |
{ | |
_fsysWatcher.Dispose(); | |
_fsysWatcher = null; | |
} | |
} | |
catch { } | |
} | |
void OnFileNotify(object sender, System.IO.FileSystemEventArgs e) | |
{ | |
try | |
{ | |
if (e.ChangeType == WatcherChangeTypes.Deleted) | |
return; | |
WaitUntilFileGetsReadable(e.FullPath); | |
ProcessFile(e.FullPath); | |
} | |
catch (Exception ex) | |
{ | |
writeLine(ex.ToString()); | |
} | |
} | |
static void WaitUntilFileGetsReadable(string filename) | |
{ | |
const int C_FOLDERWATCH_DELAY = 500; | |
for (; ; ) | |
{ | |
try | |
{ | |
using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.None)) | |
{ | |
break; | |
} | |
} | |
catch | |
{ | |
System.Threading.Thread.Sleep(C_FOLDERWATCH_DELAY); | |
} | |
} | |
} | |
string _cachePath; | |
string _outDir; | |
FileSystemWatcher _fsysWatcher = null; | |
static Dictionary<ImageFormat, string> s_type2Ext = new Dictionary<ImageFormat, string>(); | |
static ChromeImageExtractor() | |
{ | |
s_type2Ext[ImageFormat.Bmp] = ".bmp"; | |
s_type2Ext[ImageFormat.Emf] = ".emf"; | |
s_type2Ext[ImageFormat.Exif] = ".jpg"; | |
s_type2Ext[ImageFormat.Gif] = ".gif"; | |
s_type2Ext[ImageFormat.Icon] = ".ico"; | |
s_type2Ext[ImageFormat.Jpeg] = ".bmp"; | |
s_type2Ext[ImageFormat.Bmp] = ".jpg"; | |
s_type2Ext[ImageFormat.Png] = ".png"; | |
s_type2Ext[ImageFormat.Tiff] = ".tif"; | |
s_type2Ext[ImageFormat.Wmf] = ".wmf"; | |
} | |
public event WriteLineDelegate WriteLine; | |
private void writeLine(string format, params object[] args) | |
{ | |
if (WriteLine != null) | |
WriteLine(format, args); | |
} | |
private bool isFLV(string fileName) | |
{ | |
using (var f = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.ReadWrite)) | |
{ | |
if (f.Length > 1024 * 1024) | |
{ | |
var buf = new byte[3]; | |
f.Read(buf, 0, 3); | |
if (buf[0] == 'F' && buf[1] == 'L' && buf[2] == 'V') | |
{ | |
return true; | |
} | |
} | |
} | |
return false; | |
} | |
public bool ProcessFile(string fileName) | |
{ | |
try | |
{ | |
string body = Path.GetFileName(fileName); | |
string outfn = Path.Combine(_outDir, body + ".jpg"); | |
if (File.Exists(outfn) && File.GetLastWriteTimeUtc(outfn) < File.GetLastWriteTimeUtc(fileName)) | |
{ | |
writeLine("{0}: Skipped.", body); | |
return false; | |
} | |
if (isFLV(fileName)) | |
{ | |
Directory.CreateDirectory(_outDir); | |
File.Copy(fileName, Path.Combine(_outDir, body + ".flv")); | |
return true; | |
} | |
using (var bmp = new Bitmap(fileName)) | |
{ | |
if (bmp.Width < 300 || bmp.Height < 300) | |
{ | |
writeLine("{0}: Skipped; too small.", body); | |
return false; | |
} | |
string ext = s_type2Ext.ContainsKey(bmp.RawFormat) ? | |
s_type2Ext[bmp.RawFormat] : ""; | |
writeLine( | |
"{0}: {1} {2}x{3} -> {4}", | |
body, | |
ext, | |
bmp.Width, bmp.Height, outfn); | |
Directory.CreateDirectory(_outDir); | |
bmp.Save(outfn); | |
} | |
return true; | |
} | |
catch (ArgumentException) | |
{ | |
return false; | |
} | |
catch (Exception e) | |
{ | |
writeLine(e.ToString()); | |
return false; | |
} | |
} | |
public void Mirror() | |
{ | |
writeLine("Checking existing files..."); | |
foreach (string fn in Directory.GetFiles(_cachePath)) | |
ProcessFile(fn); | |
} | |
static void Main(string[] args) | |
{ | |
try | |
{ | |
AllocConsole(); | |
Console.CancelKeyPress += (o, e) => { throw new ApplicationException("Interrupted by Ctrl-C"); }; | |
using (var watcher = new ChromeImageExtractor()) | |
{ | |
watcher.WriteLine += (f, a) => Console.WriteLine(f, a); | |
watcher.Mirror(); | |
watcher.StartWatch(); | |
Console.WriteLine("\r\nHit [Enter] to terminate the process."); | |
Console.ReadKey(); | |
} | |
} | |
catch (Exception e) | |
{ | |
Console.WriteLine(e.ToString()); | |
Console.WriteLine("\r\nHit [Enter] to terminate the process."); | |
Console.ReadKey(); | |
} | |
} | |
[DllImport("kernel32.dll")] | |
private static extern bool AllocConsole(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment