Skip to content

Instantly share code, notes, and snippets.

@espresso3389
Created June 1, 2016 20:36
Show Gist options
  • Save espresso3389/6c0e0ebcea8c2d7f07b8e2542b6e5e16 to your computer and use it in GitHub Desktop.
Save espresso3389/6c0e0ebcea8c2d7f07b8e2542b6e5e16 to your computer and use it in GitHub Desktop.
Chrome Cache Retriever
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