<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: mich</title>
    <description>The latest articles on DEV Community by mich (@mich_cook).</description>
    <link>https://dev.to/mich_cook</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F430255%2F11bc2510-4a5c-47ba-80ab-93eeaf0214e9.png</url>
      <title>DEV Community: mich</title>
      <link>https://dev.to/mich_cook</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mich_cook"/>
    <language>en</language>
    <item>
      <title>Shorter Way to Upload to Google Cloud Storage (Just Send the Buffer)</title>
      <dc:creator>mich</dc:creator>
      <pubDate>Tue, 21 Jul 2020 23:43:06 +0000</pubDate>
      <link>https://dev.to/mich_cook/shorter-way-to-upload-to-google-cloud-storage-just-send-the-buffer-5h8i</link>
      <guid>https://dev.to/mich_cook/shorter-way-to-upload-to-google-cloud-storage-just-send-the-buffer-5h8i</guid>
      <description>&lt;p&gt;Part of my current project is to take a disk image that's uploaded by the user and place it in google cloud storage. This is something that seems like it should be straightforward and it started close to that then moved further in that direction.&lt;/p&gt;

&lt;p&gt;I started with this &lt;a href="https://medium.com/@olamilekan001/image-upload-with-google-cloud-storage-and-node-js-a1cf9baa1876"&gt;excellent thorough writeup&lt;/a&gt; and picked out the stuff that helped flesh out the mechanics. I use &lt;code&gt;express-fileupload&lt;/code&gt; instead of &lt;code&gt;multer&lt;/code&gt; just because I like it better for no other objective reason I could really name other than the free md5 sum which I use to know which files are duplicates based on their content.&lt;/p&gt;

&lt;p&gt;Many of the examples I was seeing used &lt;code&gt;.createWriteStream()&lt;/code&gt; which is likely a really good "learn the long way first" route. However there's a much simplified version (which is the job of a library) called &lt;code&gt;.save()&lt;/code&gt;. Your files don't have a content type, but that can be added with a google cloud function (especially if you're already going to do other stuff with it) or a second call to the API after the upload. Thanks to &lt;a href="https://github.com/googleapis/google-cloud-node/issues/2334"&gt;this thread&lt;/a&gt; for pointing out this shortcut over three years ago. &lt;/p&gt;

&lt;p&gt;Below is code that's roughly what I use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Cloud&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@google-cloud/storage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// currently @5.1.2&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Storage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Cloud&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// same storage object for all uploads&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Storage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keyFilename&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./PATH/MY_GCP_KEY.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// same bucket for all uploads&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MY_BUCKET&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uploadDiskImage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;buffer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fileHandle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;fileExists&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fileHandle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileExists&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;fileHandle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;uploadDiskImage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I believe most of it is pretty simple to read which was largely the point of this post. It could probably get simplified quite a bit more (the &lt;code&gt;.exists()&lt;/code&gt; feels like an area of opportunity), but for now it's not too shabby.&lt;/p&gt;

</description>
      <category>googlecloud</category>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>Doing the Port Myself</title>
      <dc:creator>mich</dc:creator>
      <pubDate>Sat, 18 Jul 2020 06:52:57 +0000</pubDate>
      <link>https://dev.to/mich_cook/doing-the-port-myself-17fl</link>
      <guid>https://dev.to/mich_cook/doing-the-port-myself-17fl</guid>
      <description>&lt;p&gt;Part of the catalog software that I mentioned in my previous post will take a disk image, validate it, and get a listing of the files on the disk as well as a few other details (disk name, blocks free).&lt;/p&gt;

&lt;p&gt;As I also mentioned previously, there's already software out there that does this called &lt;code&gt;c1541&lt;/code&gt; that's part of the VICE emulator. It was done and seemed that it would be easy to use (it's easy to use on a local machine), but this meant that I would need to use google run. Not that I mind that, but it meant building docker a container to have google, well, run.&lt;/p&gt;

&lt;p&gt;Starting to get my docker VM running, it ALSO reported that it was out of space (it would appear that 10GB allocations of fixed disks isn't a very good idea). So instead of going through the whole process like I did last time, I went a different direction that I had planned to do later regardless: port &lt;code&gt;c1541&lt;/code&gt; to JavaScript myself. I looked to see if there was anything that already existed and nothing really hit the mark that I needed.&lt;/p&gt;

&lt;p&gt;Loading a file is pretty easy in node.js. I just used &lt;a href="https://nodejs.org/api/fs.html#fs_fs_readfilesync_path_options"&gt;fs.readFileSync&lt;/a&gt; since I really didn't need async and there wasn't much point in wrapping everything else in a promise. From there it was just jumping around the buffer.&lt;/p&gt;

&lt;p&gt;I found &lt;a href="http://petlibrary.tripod.com/D64.HTM"&gt;two&lt;/a&gt; different &lt;a href="http://unusedino.de/ec64/technical/formats/d64.html"&gt;sources&lt;/a&gt; that had almost identical information about the bytes of a .d64 file that appeared to both copy from roughtly the same place. It was fun to see that tripod is still around. I remember them from many years ago.&lt;/p&gt;

&lt;p&gt;Using these sources, I was able to navigate a bit around the file buffer to get the parts that I needed. It was so simple since you can seek a node.js buffer just like it's an array. So &lt;code&gt;disk[0x16500]&lt;/code&gt; gives me the byte at 0x16500. Pretty spiffy!&lt;/p&gt;

&lt;p&gt;I'll probably write more about the actual code soon, but in the meantime you can take a look at the &lt;a href="https://github.com/mich-cook/d64-utils"&gt;github project&lt;/a&gt; and/or play with the &lt;a href="https://www.npmjs.com/package/@mich-cook/d64-utils"&gt;npm package&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>npm</category>
      <category>node</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Starting in the Middle</title>
      <dc:creator>mich</dc:creator>
      <pubDate>Mon, 13 Jul 2020 06:11:05 +0000</pubDate>
      <link>https://dev.to/mich_cook/starting-in-the-middle-je7</link>
      <guid>https://dev.to/mich_cook/starting-in-the-middle-je7</guid>
      <description>&lt;p&gt;I'm in the middle of building a fun little c64 disk catalog app for myself. The part which currently has my attention is handling the disk uploads. I have a react front end that's uploading the images to my google cloud storage bucket. I want to validate the disk image and get the listing of files for the disk. That's the start of today's adventure.&lt;/p&gt;

&lt;p&gt;There's already software called &lt;code&gt;c1541&lt;/code&gt; that's bundled with the vice emulator AND it's already available for ubuntu. Yay! However, this means that I'm doing a google run instead of a google function. Functions can trigger themselves on a file upload, but run needs to pipe through pubsub. Bummer! Well, kind of. I get to play with more toys so that's fun. It's probably faster to do the port later and get this done now. &lt;/p&gt;

&lt;p&gt;In my ubuntu 20 VM (host still running 18 until I get the backup and other prep done), I run through the &lt;a href="https://cloud.google.com/sdk/docs#deb"&gt;install steps&lt;/a&gt; and have somehow popped over my 10GB fixed disk size! No clue if the apt install of the SDK worked, but I'm assuming that it didn't.&lt;/p&gt;

&lt;p&gt;I found a &lt;a href="https://www.linuxbabe.com/virtualbox/how-to-increase-virtualbox-disk-size-for-fixed-size-disks"&gt;quick tutorial&lt;/a&gt; for solving a disk that's too small. One thing that should be more clear is that the VM needs to be turned off completely before the storage can be changed. It can't just be in a saved state. This makes sense when you look at the whole process, but if you're just stepping through then you might run into this problem. The other thing that's obvious after a second, but can cause a stumble is to make sure you resize the extended partition that holds your partition so that you &lt;strong&gt;can&lt;/strong&gt; resize your partition larger.&lt;/p&gt;

&lt;p&gt;After fixing the partition and finishing the gcloud SDK install (on this newish ub20 install, I had to &lt;code&gt;sudo apt install curl&lt;/code&gt;), I appear to be up and running with gsutil. Let's get this bucket wired.&lt;/p&gt;

</description>
      <category>googlecloud</category>
      <category>ubuntu</category>
    </item>
  </channel>
</rss>
