I code in TypeScript daily but there was something missing from my workflow. I was developing applications in
TypeScript but I was debugging them in JavaScript. Since my go to browser-of-choice is Chrome, I decided to rectify this issue.
TypeScript Console is a bare-bones Chrome extension that allows one to execute TypeScript to the console. It is split into two Ace editors — TypeScript on the right, JavaScript on the left. Typing into the TypeScript editor automatically interrupts it to JavaScript. Hitting ‘CTRL+Enter’ executes the code.
As usual — the code and the extension itself are on my GitHub. Once I add a few more features (history, smart indent) I’ll be adding it to the Chrome Store.
When Marvel originally tried to give away 700+ plus comics — their servers crashed. If you were lucky enough to re-signup once Marvel got everything sorted out, invites/instructions are now going out on how to download your free digital comics.
One small problem. Downloading them all is painful…really painful with all the clicking of the ‘Add Comic’ and ‘Next’ buttons. Don’t fret — there is an easier way. Just open a JavaScript console in your browser and run the following.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// Loop through all the pages (Next) for (var page = 1; page < 20; page++) { //Trigger the click event on the 'Add Comic' button jQuery.each($('.addComicLink'), function (i, val) { if ($(val).text() == "Add Comic") { $(val).click(); } }); // Goto the next page of all sections for (var sec = 1; sec < 20; sec++) { GoToNextAdHocPage(sec); } } |
The Katana Project is a server implementation of the Open Web Interface for .NET (OWIN) specification. In
simple terms: It is a web server that implements an agreed upon standard for communication between the host (server), middleware and your application .
For my current project, I needed a way for Katana to serve files directly from an assembly via embedded resources. Since Katana was designed to be very extensible – it is trivial to add the functionality that I needed. Katana provides a StaticFile middleware out of the box, so by injecting a custom FileSystemProvider we can serve files directly from an assembly.
We’ll start out by telling the StaticFile middleware to use our custom ResourceFileSystemProvider.
|
1 2 3 4 |
app.UseStaticFiles(options => { options.WithFileSystem(new ResourceFileSystemProvider()); }); |
For the actual ResourceFileSystemProvider – we need to implement IFileSystem. IFileSystem is an interface of just two methods, one to get information about a directory and the other to get information about a specific file. Both of these methods return a bool with an out parameter of type IFileInfo.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Microsoft.Owin.FileSystems; namespace Metrical.Providers { public class ResourceFileSystemProvider : IFileSystem { public bool TryGetDirectoryContents(string subpath, out IEnumerable<IFileInfo> contents) { throw new NotImplementedException(); } public bool TryGetFileInfo(string subpath, out IFileInfo fileInfo) { var flatPath = subpath.Replace('/', '.'); var assembly = Assembly.GetExecutingAssembly(); var assemblyName = assembly.GetName().Name; var path = String.Format("{0}{1}", assemblyName, flatPath); var resourceNames = assembly.GetManifestResourceNames(); if (resourceNames.Contains(path)) { fileInfo = new ResourceFileInfo(path); return true; } fileInfo = null; return false; } } } |
IFileInfo encapsulates information about a file (or directory). It also exposes a stream of the file contents. As you can see we just pass in a reference to the currently executing assembly and return the ManifestResourceStream.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
using Microsoft.Owin.FileSystems; using System; using System.Reflection; namespace Metrical.Providers { public class ResourceFileInfo : IFileInfo { private string _filePath; private Assembly _assembly; public ResourceFileInfo(string file) { _filePath = file; _assembly = Assembly.GetExecutingAssembly(); } public System.IO.Stream CreateReadStream() { return _assembly.GetManifestResourceStream(_filePath); } public bool IsDirectory { get { return false; } } public DateTime LastModified { get { return DateTime.Now; } } public long Length { get { using (var stream = CreateReadStream()) { return stream.Length; } } } public string Name { get { return _filePath; } } public string PhysicalPath { get { return _filePath; } } } } |