404
+ +Page not found :(
+The requested page could not be found.
+diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4947545 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +FROM ruby:3.4 + +# Set the working directory +WORKDIR /site + +# Copy the site files +COPY blog /site + +# Install site dependencies +RUN bundle install + +# Build the site +RUN bundle exec jekyll build + +# Copy the built site to a separate directory +RUN mkdir /output && cp -r _site/* /output/ + +# Expose Jekyll default port +EXPOSE 4000 + +# Serve the site +CMD ["bundle", "exec", "jekyll", "serve", "--host", "0.0.0.0", "--watch", "--drafts"] diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index a643e9f..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,74 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - addressable (2.5.2) - public_suffix (>= 2.0.2, < 4.0) - colorator (1.1.0) - concurrent-ruby (1.1.4) - em-websocket (0.5.1) - eventmachine (>= 0.12.9) - http_parser.rb (~> 0.6.0) - eventmachine (1.2.7) - ffi (1.9.25) - forwardable-extended (2.6.0) - http_parser.rb (0.6.0) - i18n (0.9.5) - concurrent-ruby (~> 1.0) - jekyll (3.8.5) - addressable (~> 2.4) - colorator (~> 1.0) - em-websocket (~> 0.5) - i18n (~> 0.7) - jekyll-sass-converter (~> 1.0) - jekyll-watch (~> 2.0) - kramdown (~> 1.14) - liquid (~> 4.0) - mercenary (~> 0.3.3) - pathutil (~> 0.9) - rouge (>= 1.7, < 4) - safe_yaml (~> 1.0) - jekyll-feed (0.11.0) - jekyll (~> 3.3) - jekyll-sass-converter (1.5.2) - sass (~> 3.4) - jekyll-seo-tag (2.5.0) - jekyll (~> 3.3) - jekyll-watch (2.1.2) - listen (~> 3.0) - kramdown (1.17.0) - liquid (4.0.1) - listen (3.1.5) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - ruby_dep (~> 1.2) - mercenary (0.3.6) - minima (2.5.0) - jekyll (~> 3.5) - jekyll-feed (~> 0.9) - jekyll-seo-tag (~> 2.1) - pathutil (0.16.2) - forwardable-extended (~> 2.6) - public_suffix (3.0.3) - rb-fsevent (0.10.3) - rb-inotify (0.10.0) - ffi (~> 1.0) - rouge (3.3.0) - ruby_dep (1.5.0) - safe_yaml (1.0.4) - sass (3.7.2) - sass-listen (~> 4.0.0) - sass-listen (4.0.0) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - -PLATFORMS - ruby - -DEPENDENCIES - jekyll (~> 3.8.5) - jekyll-feed (~> 0.6) - minima (~> 2.0) - tzinfo-data - -BUNDLED WITH - 1.17.2 diff --git a/_posts/2025-2-2-blah.markdown b/_posts/2025-2-2-blah.markdown deleted file mode 100644 index fc5909f..0000000 --- a/_posts/2025-2-2-blah.markdown +++ /dev/null @@ -1,8 +0,0 @@ ---- -layout: post -title: "Hope this works" -date: 2025-02-08T18:04:18.692Z -categories: utilities ---- - -Blah blah blah blah diff --git a/.gitignore b/blog/.gitignore similarity index 100% rename from .gitignore rename to blog/.gitignore diff --git a/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Cache/b7/9606fb3afea5bd1609ed40b622142f1c98125abcfe89a76a661b0e8e343910 b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Cache/b7/9606fb3afea5bd1609ed40b622142f1c98125abcfe89a76a661b0e8e343910 new file mode 100644 index 0000000..7691ece --- /dev/null +++ b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Cache/b7/9606fb3afea5bd1609ed40b622142f1c98125abcfe89a76a661b0e8e343910 @@ -0,0 +1 @@ +I" {"title" => "š² johncsimon.github.io š¦", "author" => "Abhinav Saxena", "url" => "http://0.0.0.0:4000", "description" => "got some downtime so how's about we starts ourselves a blog ...", "favicon" => "./logo.png", "remote_theme" => "abhinavs/moonwalk", "theme_config" => {"appearance" => "dark", "back_home_text" => "home..", "date_format" => "%Y-%m-%d", "show_description" => true, "show_navbar" => true, "show_footer" => true, "show_projects" => true, "show_old_projects" => true, "show_misc_list" => false}, "sass" => {"style" => :compressed}, "source" => "/site", "destination" => "/site/_site", "collections_dir" => "", "cache_dir" => ".jekyll-cache", "plugins_dir" => "_plugins", "layouts_dir" => "_layouts", "data_dir" => "_data", "includes_dir" => "_includes", "collections" => {"posts" => {"output" => true, "permalink" => "/:categories/:year/:month/:day/:title:output_ext"}}, "safe" => false, "include" => [".htaccess"], "exclude" => [".sass-cache", ".jekyll-cache", "gemfiles", "Gemfile", "Gemfile.lock", "node_modules", "vendor/bundle/", "vendor/cache/", "vendor/gems/", "vendor/ruby/"], "keep_files" => [".git", ".svn"], "encoding" => "utf-8", "markdown_ext" => "markdown,mkdown,mkdn,mkd,md", "strict_front_matter" => false, "show_drafts" => true, "limit_posts" => 0, "future" => false, "unpublished" => false, "whitelist" => [], "plugins" => ["jekyll-feed"], "markdown" => "kramdown", "highlighter" => "rouge", "lsi" => false, "excerpt_separator" => "\n\n", "incremental" => false, "detach" => false, "port" => "4000", "host" => "0.0.0.0", "baseurl" => nil, "show_dir_listing" => false, "permalink" => "date", "paginate_path" => "/page:num", "timezone" => nil, "quiet" => false, "verbose" => false, "defaults" => [], "liquid" => {"error_mode" => "warn", "strict_filters" => false, "strict_variables" => false}, "kramdown" => {"auto_ids" => true, "toc_levels" => [1, 2, 3, 4, 5, 6], "entity_output" => "as_char", "smart_quotes" => "lsquo,rsquo,ldquo,rdquo", "input" => "GFM", "hard_wrap" => false, "guess_lang" => true, "footnote_nr" => 1, "show_warnings" => false, "syntax_highlighter" => "rouge", "syntax_highlighter_opts" => {default_lang: "plaintext", guess_lang: true}, "coderay" => {}}, "github_username" => "johncsimon", "theme" => "moonwalk", "watch" => true, "livereload_port" => 35729, "serving" => true}:ET \ No newline at end of file diff --git a/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/06/753e995b3c003834d56acad82fff6bf9825fdbd0513298290d61eb63dff9e8 b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/06/753e995b3c003834d56acad82fff6bf9825fdbd0513298290d61eb63dff9e8 new file mode 100644 index 0000000..4defdad --- /dev/null +++ b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/06/753e995b3c003834d56acad82fff6bf9825fdbd0513298290d61eb63dff9e8 @@ -0,0 +1,3 @@ +I"K
Iām currently reading a contemporary history of Steve Jobsās time with the creation and unraveling of NeXT Computer - Steve Jobs and the NeXT Big Thing.
+
got some downtime so howās about we starts ourselves a blog ā¦
+:ET \ No newline at end of file diff --git a/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/28/409282bc7b120130c52502bbf529c1f4888a953e7404ed794fc89f19ad0b40 b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/28/409282bc7b120130c52502bbf529c1f4888a953e7404ed794fc89f19ad0b40 new file mode 100644 index 0000000..ea85f17 --- /dev/null +++ b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/28/409282bc7b120130c52502bbf529c1f4888a953e7404ed794fc89f19ad0b40 @@ -0,0 +1,2 @@ +I"Iām a software dev with Go, Javascript and C#. Iām writing this blog to better at writing and to document my explorations.
+:ET \ No newline at end of file diff --git a/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/39/10527bad802f5b463cf43eff4825977cf595078493d02f3cbf7409f0098e86 b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/39/10527bad802f5b463cf43eff4825977cf595078493d02f3cbf7409f0098e86 new file mode 100644 index 0000000..d225893 --- /dev/null +++ b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/39/10527bad802f5b463cf43eff4825977cf595078493d02f3cbf7409f0098e86 @@ -0,0 +1,222 @@ +I"b.I like to play around with lots of different programming languages, but install too many and they pollute your working environment, so itās better to have them installed as a user instead of root.
+Hereās a way to get several of them installed into your unix user directory.
+If things go wrong, or you get bored you can easily rm -rf the installation.
Letās get ourselves a minimal debian environment. Iām using docker here, but you can use a native install, or a VM, or Windows Services for Linux with the ubuntu install.
+john@BigBox:~/git/JohnCSimon.github.io$ sudo docker run -ti debian /bin/bash
+Unable to find image 'debian:latest' locally
+latest: Pulling from library/debian
+cd8eada9c7bb: Pull complete
+Digest: sha256:58a80e0b6aa4d960ee2a5452b0230c406c47ed30a66555ba753c8e1710a434f5
+Status: Downloaded newer image for debian:latest
+root@6d933dddbbcd:/#
+Just to satisfy my OCD letās get the latest updates.
+ +apt update && apt upgrade -y
apt install gnupg2 curl procps -y
+ Installs gpg2, curl and ps
gpg2 --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
\curl -sSL https://get.rvm.io | bash -s stable
To start using RVM you need to run source /etc/profile.d/rvm.sh or re-login to re-load ~/.profile
From here you can run - rvm list known and youāll see a list of ruby flavors and individual versions.
# MRI Rubies
+[ruby-]1.8.6[-p420]
+[ruby-]1.8.7[-head] # security released on head
+[ruby-]1.9.1[-p431]
+[ruby-]1.9.2[-p330]
+[ruby-]1.9.3[-p551]
+[ruby-]2.0.0[-p648]
+[ruby-]2.1[.10]
+[ruby-]2.2[.10]
+[ruby-]2.3[.8]
+[ruby-]2.4[.5]
+[ruby-]2.5[.3]
+[ruby-]2.6[.0]
+MRI Ruby is the reference version of Ruby so letās install the latest version.
+ +rvm install ruby-2.6.0
Iām running debian and rvm might ask for your root password to install some prerequsites from apt before compiling a new version.
+ +Congrats, you now have a ruby install
+ +$ ruby -v
+ruby 2.6.0p0 (2018-12-25 revision 66547) [x86_64-linux]
+from here you can now do whatever since Iām blogging this using jekyll
+ +gem install bundler jekyll
Go is a language that releases new versions on a regular basis.
+Thereās a similar tool to rvm called gvm. Itās a āgo version managerā available from here https://github.com/moovweb/gvm thatāll let you install multiple versions and set $GOPATH and $GOROOT.
as a regular user:
+$ bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
+Cloning from https://github.com/moovweb/gvm.git to /root/.gvm
+No existing Go versions detected
+Installed GVM v1.0.22
+
+Please restart your terminal session or to get started right away run
+ `source /root/.gvm/scripts/gvm`
+you should be able to run and see
+$ gvm version
+Go Version Manager v1.0.22 installed at /home/john/.gvm
+Run gvm listall
+which will give you a list of all the available versions of go.
$gvm listall
+
+gvm gos (available)
+
+ go1
+ go1.0.1
+ ...
+ go1.11rc1
+ go1.11rc2
+ go1.11.1
+ go1.11.2
+ go1.11.3
+ go1.11.4
+ go1.12beta1
+ go1.12beta2
+of which there are entirely too many.
+ +From here, we can install go as our user via binary here:
+ +gvm install go1.4 -B
try it out
+$ go version
+go version go1.4 linux/amd64
+We can see it gets installed here:
+$ echo $GOROOT
+/home/john/.gvm/gos/go1.4
+From the gvm link earlier, in order to compile a go build environment for versions 1.5 on we require another go build environment. +Go compiles itself! Neat huh?
+ +As of now the latest version is go1.11.4
+$ export GOROOT_BOOTSTRAP=$GOROOT
+$ gvm install go1.11.4
+$ go version
+go version go1.4 linux/amd64
+you can run
+gvm use - select a go version to use (--default to set permanently)
$ gvm use go1.11.4 --default
+Now using version go1.11.4
+$ go version
+go version go1.11.4 linux/amd64
+$ echo $GOROOT
+/home/john/.gvm/gos/go1.11.4
+$ echo $GOPATH
+/home/john/.gvm/pkgsets/go1.11.4/global
+$ ls /home/john/.gvm/gos/go1.11.4
+AUTHORS CONTRIBUTING.md CONTRIBUTORS LICENSE PATENTS README.md VERSION api bin doc favicon.ico lib manifest misc pkg robots.txt src test
+ls $GOPATH
+overlay pkg src
+Be sure to set ādefault so you keep the same version when you relaunch the shell, so that whatever you install stays where you expect it.
+ +node.js, the server side javascript framework
+ +nvm is Node Version Manager. Install it like this:
+curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
Since there are major revisions to the javascript language between node 4, 6, 8 Iāve found Iāve had to switch more often between these versions according to project than I did with other languages.
+ +You can run nvm ls-remote and get a list of all the node versions available
$ nvm
+Example:
+ nvm install 8.0.0 Install a specific version number
+ nvm use 8.0 Use the latest available 8.0.x release
+ nvm run 6.10.3 app.js Run app.js using node 6.10.3
+ nvm exec 4.8.3 node app.js Run `node app.js` with the PATH pointing to node 4.8.3
+ nvm alias default 8.1.0 Set default node version on a shell
+ nvm alias default node Always default to the latest available node version on a shell
+so if you run
+ +$ nvm install 10
+Downloading and installing node v10.15.0...
+Downloading https://nodejs.org/dist/v10.15.0/node-v10.15.0-linux-x64.tar.gz...
+######################################################################## 100.0%
+Computing checksum with sha256sum
+Checksums matched!
+Now using node v10.15.0 (npm v6.4.1)
+Creating default alias: default -> 10 (-> v10.15.0)
+
+$ whereis node
+node: /home/john/.nvm/versions/node/v10.15.0/bin/node
+and you can set it to be the default so the setting persists between sessions
+nvm alias default 10
+So now you can run:
+$ node -v
+v10.15.0
+$ npm -v
+6.4.1
+Rust is another language that sees regular updates. Youāll just have to check which is the version for the 2015 and 2018 edition.
+ +curl https://sh.rustup.rs -sSf | sh
+
+
+
+Current installation options:
+
+ default host triple: x86_64-unknown-linux-gnu
+ default toolchain: stable
+ modify PATH variable: yes
+
+1) Proceed with installation (default)
+2) Customize installation
+3) Cancel installation
+>
+
+select 1
+
+To configure your current shell run source $HOME/.cargo/env
+add $HOME/.cargo/env to your path in .bashrc
$ whereis cargo
+cargo: /home/john/.cargo/bin/cargo
+$ whereis rustc
+cargo: /home/john/.cargo/bin/rustc
+I like to play around with lots of different programming languages, but install too many and they pollute your working environment, so itās better to have them installed as a user instead of root.
+Hereās a way to get several of them installed into your unix user directory.
+If things go wrong, or you get bored you can easily rm -rf the installation.
Recently I had to write a file uploader for AWS S3 in node.
+:ET \ No newline at end of file diff --git a/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/69/5f773373ce5344de744369cb7f5a8494d0c68bc72c923ef1102e0b9ce4d1c1 b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/69/5f773373ce5344de744369cb7f5a8494d0c68bc72c923ef1102e0b9ce4d1c1 new file mode 100644 index 0000000..4c0fac0 --- /dev/null +++ b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/69/5f773373ce5344de744369cb7f5a8494d0c68bc72c923ef1102e0b9ce4d1c1 @@ -0,0 +1,2 @@ +I"*Poor Manās Audiobook Reader
+:ET \ No newline at end of file diff --git a/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/8f/7e04095acc834652ced033ae7791a9c0cfcf14e4976bf40f5b7e2178e44b59 b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/8f/7e04095acc834652ced033ae7791a9c0cfcf14e4976bf40f5b7e2178e44b59 new file mode 100644 index 0000000..dee9687 --- /dev/null +++ b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/8f/7e04095acc834652ced033ae7791a9c0cfcf14e4976bf40f5b7e2178e44b59 @@ -0,0 +1,2 @@ +I"HRecently I had to write a file uploader for AWS S3 in node.
+:ET \ No newline at end of file diff --git a/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/97/67915f405b1b58b7e972bfa6bec1f96439cfb21dd68bbc76541b7a9fac8d63 b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/97/67915f405b1b58b7e972bfa6bec1f96439cfb21dd68bbc76541b7a9fac8d63 new file mode 100644 index 0000000..82caec6 --- /dev/null +++ b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/97/67915f405b1b58b7e972bfa6bec1f96439cfb21dd68bbc76541b7a9fac8d63 @@ -0,0 +1,2 @@ +I"7Gradual Typing With Javascript and VS Code
+:ET \ No newline at end of file diff --git a/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/d2/fbf109d853a7b2aac66de57c644bb3057ef9a956dc7e7634ff6e32e499e9d0 b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/d2/fbf109d853a7b2aac66de57c644bb3057ef9a956dc7e7634ff6e32e499e9d0 new file mode 100644 index 0000000..4defdad --- /dev/null +++ b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/d2/fbf109d853a7b2aac66de57c644bb3057ef9a956dc7e7634ff6e32e499e9d0 @@ -0,0 +1,3 @@ +I"KIām currently reading a contemporary history of Steve Jobsās time with the creation and unraveling of NeXT Computer - Steve Jobs and the NeXT Big Thing.
+
š² johncsimon.github.io š¦
+:ET \ No newline at end of file diff --git a/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/e3/b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/e3/b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 new file mode 100644 index 0000000..e135808 --- /dev/null +++ b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/e3/b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 @@ -0,0 +1,2 @@ +I" +:EF \ No newline at end of file diff --git a/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/ef/bc911949b3cd2c7638dc17ec49f5fa64632c0990bc22f096921658cf0600c9 b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/ef/bc911949b3cd2c7638dc17ec49f5fa64632c0990bc22f096921658cf0600c9 new file mode 100644 index 0000000..3c55e76 --- /dev/null +++ b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/ef/bc911949b3cd2c7638dc17ec49f5fa64632c0990bc22f096921658cf0600c9 @@ -0,0 +1,63 @@ +I"sIām currently reading a contemporary history of Steve Jobsās time with the creation and unraveling of NeXT Computer - Steve Jobs and the NeXT Big Thing.
+
Today, popular culture paints him as an iconic figure, but when the book was written in 1993 NeXT was a money pit, only kept alive with cash infusions from outside investors as money was burnt. Itās a wild ride, I highly recommend it, especially with hindsight.
+ +Unfortunately, reading books cover to cover is hard for me. I rely on audiobooks so I can ride the bus or do dishes while I absorb a book. Unfortunately, there is no audiobook release of this book.
+ +I found the book in PDF form on archive.org. Unfortunately PDFs are more of a page layout language like HTML instead of a store of text.
+ +If you were to use Text to Speech functionality say - speak visible content on your PC or phone on a typical website or PDF you have to ābaby sitā what is being read so that the reader doesnāt get ālostā or get caught up on footnotes or stop abruptly or be unable to handle a change in fonts. Itās not obvious how broken this functionality is.
+ +
Plain text is the best for a text to speech program. Luckily, archive.org provides a plain text version of the book which was created via optical character recognition (see the archive.org site). Short of a few footnotes, itās 95% of what we need.
+ +Except⦠text to speech generation is a high CPU task, Apple iOS doesnāt like long running tasks. You canāt scrub back and forth within a document like you can with an audio book or video. Also, it seems that this functionality within iOS doesnāt see as much development as other parts of the OS, itās generally a janky experience more optimized for the vision impaired than my use case.
+ +So, we need an offline bulk text to speech generator. Luckily, macOS provides just the very thing hidden as one of the command line utilities - this is the say utility say -v Bad\ News "Captain, you are needed on the bridge" -w 200 but it can take additional parameters (see the man pages āman sayā )
example call:
+ +say --voice=Ava \ # use '?' to get a list of all the available voices
+ --input-file Steve_Jobs_\&_the_NeXT_Big_Thing_1993_djvu.txt \ # path to plain text file
+ --data-format=m4b \ # File for the output format, m4b is the apple's audiobook equavalent of m4a see 'say --file-format='?' ' for the list of these
+ --output-file=MyOutputFile.m4b \ # output file
+ --rate=150 # speaking rate in words per minute, to your taste.
+ --progress # print the progress
+This is awesome! But after letting it run for one later the CPU is still at 100% and the process is consuming 2.3 GB of RAM and the output file MyOutoutFile.m4b is about 50 MB on disk.
+ +Something is up ⦠letās see the word count of this file.
+ +wc -lw Steve_Jobs_\&_the_NeXT_Big_Thing_1993_djvu.txt
+14908 122808 Steve_Jobs_&_the_NeXT_Big_Thing_1993_djvu.txt
+so 15000 lines, 122000 words - at 150 words / minute this is about 13 hours to read through all of it, and an audiobook of that length is roughly 1 GB.
+ +Maybe the compression or some other non-default setting is mucking with this? I remove everything except the input and output files parameters and I still see the same poor performnace.
+ +Letās break this down into 1000 line chunks, and feed each one to say.
+ +split -d -l 1000 Steve_Jobs_\&_the_NeXT_Big_Thing_1993_djvu.txt Steve1000__
+time for file in Steve1000__*; do time say \
+ -f "$file" \
+ -o "$file.m4b" \
+ --file-format=m4bf \
+ --rate=150 \
+ --progress; done
+Well thatās interesting, the process completed in 10 minutes and produced 14 files that comprise the audio book.
+ +But, I donāt want 14 parts, Iād like, say, three parts of 5000 lines each. I re-run the script ā¦
+split -d -l 5000 Steve_Jobs_\&_the_NeXT_Big_Thing_1993_djvu.txt Steve5000__
And each part takes 30 minutes to generate, a total of 90 minutes of CPU time.
+ +Intuitively, generating voice from a text file would be a linear operation. Text goes in, Audio goes out, no doubling back through a stream. But, thereās clearly a bug in the implementation of say that makes the run time be something larger than O(n^2). Apparently having say spew out hours of audio for an entire book was never a tested use case. Except, say has been around for as long as MacOSX has been around, one would think all the bugs have been worked out. Apparently not; you have to test and test and test, there will always be surprises.
+:ET \ No newline at end of file diff --git a/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/f2/c91ce0aa21e626a7eaa9ad51b40830e69be74b1d9162085924c4f233e80431 b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/f2/c91ce0aa21e626a7eaa9ad51b40830e69be74b1d9162085924c4f233e80431 new file mode 100644 index 0000000..ddcf48a --- /dev/null +++ b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/f2/c91ce0aa21e626a7eaa9ad51b40830e69be74b1d9162085924c4f233e80431 @@ -0,0 +1,71 @@ +I"ÓRecently I had to write a file uploader for AWS S3 in node.
+ +
+const AWS = require('aws-sdk');
+const s3 = new AWS.S3({ signatureVersion: 'v4' });
+
+const uploadToS3 = async () => {
+ const parameters = {
+ Bucket: s3Bucket,
+ Body: fileData,
+ };
+
+ try {
+ const { Location } = await s3.upload(parameters).promise();
+ return Location;
+ } catch (e) {
+ process.exit(1);
+ }
+};
+It looks simple enough, but youāre probably going to be spending a decent amount of time googling around for examples if the parameters in an s3 call are more than just basic hello world. Add to this javascript is a dynamically typed language; you wonāt know if your code will work until you run it, but youāre also working with Amazonās AWS SDK, itās derived from Java and expects a few things beyond just numbers and strings. In the end, youād be beating your head against the stack traces and other HTTP 400 - Bad Request errors coming out of the S3 service.
Is there anything that can help guarantee your calls to upload are legit with some sort of type checking?
Youāve probably heard of the type annotated javascript superset language TypeScript and its supplementary type definition repository Definitely Typed, which contains definitions for many popular NPM packages including AWS-SDK. This would be great except switching from Javascript to TypeScript requires adoption from the rest of the team, separate .ts files, and modifications to your build process. Is there any way to get this without futzing with your existing project?
If youāre using the Visual Studio Code editor it turns out you can enable type checking on a per-file basis by adding the comment to the beginning of the file
+ +// @ts-check
+to the beginning of your file.
+
The parameters variable is highlighted in red, and when you mouseover it youāll see:
+ +Argument of type '{ Bucket: string; Body: string; }' is not assignable to parameter of type 'PutObjectRequest'.
+ Property 'Key' is missing in type '{ Bucket: string; Body: string; }' but required in type 'PutObjectRequest'.ts(2345)
+s3.d.ts(3640, 5): 'Key' is declared here.
+const parameters: {
+ Bucket: string;
+ Body: string;
+}
+There are a bunch of things happening here!
+ +It turns out VS Code has pulled in the AWS S3 type definitions in the background. The type of the parameter parameter that s3.upload takes is called PutObjectRequest. The Type Script compiler is kvetching over a missing required field it needs to say the parameters variable is of that type. Thereās nothing stopping you from running the code as it stands here, itāll just crash at runtime.
When you add the Key parameter (the unique file key in an S3 bucket), the red squiggly underline disappears and you have a properly formed object.
The same checking is useful for output types.
+ + const { Location } = await s3.upload(parameters).promise();
+You can mouseover s3.upload and see it returns a type of AWS.S3.ManagedUpload.SendData, which means the destructuring operation { Location } is guaranteed to work and Location will be populated.
Links:
+ +Type Annotation and Checking within javascript
+ https://github.com/Microsoft/TypeScript/wiki/Type-Checking-JavaScript-Files
JSDoc - the type annotation here is based after JSDoc, so looking at the docs canāt hurt
+ +http://usejsdoc.org/tags-type.html
More to come, as with introducing gradual typing, learning this stuff is also a gradual process that pays you back the more you put into it.
+ +:ET \ No newline at end of file diff --git a/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/f3/66593c605d2558dd7641a3ec129bc92d9fc48b19eea4fe7e0d5f2f5a67b69c b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/f3/66593c605d2558dd7641a3ec129bc92d9fc48b19eea4fe7e0d5f2f5a67b69c new file mode 100644 index 0000000..b368357 --- /dev/null +++ b/blog/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/f3/66593c605d2558dd7641a3ec129bc92d9fc48b19eea4fe7e0d5f2f5a67b69c @@ -0,0 +1,4 @@ +I"¦I like to play around with lots of different programming languages, but install too many and they pollute your working environment, so itās better to have them installed as a user instead of root.
+Hereās a way to get several of them installed into your unix user directory.
+If things go wrong, or you get bored you can easily rm -rf the installation.
The Perspicacious Polyglotās Programming Language Plethora
+:ET \ No newline at end of file diff --git a/blog/.nojekyll b/blog/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/blog/404.html similarity index 100% rename from 404.html rename to blog/404.html diff --git a/Gemfile b/blog/Gemfile similarity index 88% rename from Gemfile rename to blog/Gemfile index 2bf1ac7..4f30904 100644 --- a/Gemfile +++ b/blog/Gemfile @@ -8,10 +8,11 @@ source "https://rubygems.org" # # This will help ensure the proper Jekyll version is running. # Happy Jekylling! -gem "jekyll", "~> 3.8.5" +gem "jekyll" # This is the default theme for new Jekyll sites. You may change this to anything you like. -gem "minima", "~> 2.0" +# gem "minima" +gem 'moonwalk' # If you want to use GitHub Pages, remove the "gem "jekyll"" above and # uncomment the line below. To upgrade, run `bundle update github-pages`. @@ -28,3 +29,11 @@ gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby] # Performance-booster for watching directories on Windows gem "wdm", "~> 0.1.0" if Gem.win_platform? +# gem "csv", "~> 3.3.2" + + +gem 'webrick' +gem 'base64' +gem 'csv' +gem 'logger' +gem 'bigdecimal' \ No newline at end of file diff --git a/blog/Gemfile.lock b/blog/Gemfile.lock new file mode 100644 index 0000000..073365a --- /dev/null +++ b/blog/Gemfile.lock @@ -0,0 +1,108 @@ +GEM + remote: https://rubygems.org/ + specs: + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + base64 (0.2.0) + bigdecimal (3.1.9) + colorator (1.1.0) + concurrent-ruby (1.3.5) + csv (3.3.2) + em-websocket (0.5.3) + eventmachine (>= 0.12.9) + http_parser.rb (~> 0) + eventmachine (1.2.7) + ffi (1.17.1) + ffi (1.17.1-aarch64-linux-gnu) + ffi (1.17.1-aarch64-linux-musl) + ffi (1.17.1-arm-linux-gnu) + ffi (1.17.1-arm-linux-musl) + ffi (1.17.1-arm64-darwin) + ffi (1.17.1-x86-linux-gnu) + ffi (1.17.1-x86-linux-musl) + ffi (1.17.1-x86_64-darwin) + ffi (1.17.1-x86_64-linux-gnu) + ffi (1.17.1-x86_64-linux-musl) + forwardable-extended (2.6.0) + http_parser.rb (0.8.0) + i18n (1.14.7) + concurrent-ruby (~> 1.0) + jekyll (4.1.1) + addressable (~> 2.4) + colorator (~> 1.0) + em-websocket (~> 0.5) + i18n (~> 1.0) + jekyll-sass-converter (~> 2.0) + jekyll-watch (~> 2.0) + kramdown (~> 2.1) + kramdown-parser-gfm (~> 1.0) + liquid (~> 4.0) + mercenary (~> 0.4.0) + pathutil (~> 0.9) + rouge (~> 3.0) + safe_yaml (~> 1.0) + terminal-table (~> 1.8) + jekyll-feed (0.15.1) + jekyll (>= 3.7, < 5.0) + jekyll-sass-converter (2.2.0) + sassc (> 2.0.1, < 3.0) + jekyll-seo-tag (2.7.1) + jekyll (>= 3.8, < 5.0) + jekyll-watch (2.2.1) + listen (~> 3.0) + kramdown (2.4.0) + rexml + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + liquid (4.0.4) + listen (3.9.0) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + logger (1.6.5) + mercenary (0.4.0) + moonwalk (0.0.2) + jekyll (~> 4.1.1) + jekyll-feed (~> 0.15.0) + jekyll-seo-tag (~> 2.7.1) + pathutil (0.16.2) + forwardable-extended (~> 2.6) + public_suffix (5.1.1) + rb-fsevent (0.11.2) + rb-inotify (0.11.1) + ffi (~> 1.0) + rexml (3.4.0) + rouge (3.30.0) + safe_yaml (1.0.5) + sassc (2.4.0) + ffi (~> 1.9) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + unicode-display_width (1.8.0) + webrick (1.9.1) + +PLATFORMS + aarch64-linux-gnu + aarch64-linux-musl + arm-linux-gnu + arm-linux-musl + arm64-darwin + ruby + x86-linux-gnu + x86-linux-musl + x86_64-darwin + x86_64-linux-gnu + x86_64-linux-musl + +DEPENDENCIES + base64 + bigdecimal + csv + jekyll + jekyll-feed (~> 0.6) + logger + moonwalk + tzinfo-data + webrick + +BUNDLED WITH + 2.6.3 diff --git a/_config.yml b/blog/_config.yml similarity index 90% rename from _config.yml rename to blog/_config.yml index 86d448b..f61c789 100644 --- a/_config.yml +++ b/blog/_config.yml @@ -23,7 +23,11 @@ github_username: johncsimon # Build settings markdown: kramdown -theme: minima +# remote_theme: pages-themes/hacker@v0.2.0 +theme: moonwalk + +# plugins: +# - jekyll-remote-theme # add this line to the plugins list if you already have one plugins: - jekyll-feed diff --git a/_posts/2018-12-30-javascript-gradual-typing.markdown b/blog/_posts/2018-12-30-javascript-gradual-typing.markdown similarity index 93% rename from _posts/2018-12-30-javascript-gradual-typing.markdown rename to blog/_posts/2018-12-30-javascript-gradual-typing.markdown index 5c94ffe..1f52bc3 100644 --- a/_posts/2018-12-30-javascript-gradual-typing.markdown +++ b/blog/_posts/2018-12-30-javascript-gradual-typing.markdown @@ -2,10 +2,10 @@ layout: post title: "Gradual Typing With Javascript and VS Code" date: 2018-12-29 11:40:43 -0800 -categories: javascript +categories: posts --- -Recently I had to write a file uploader for AWS S3 in node. +Recently I had to write a file uploader for AWS S3 in node. ```javascript @@ -27,18 +27,19 @@ const uploadToS3 = async () => { }; ``` - It looks simple enough, but you're probably going to be spending a decent amount of time googling around for examples if the parameters in an s3 call are more than just basic hello world. Add to this javascript is a dynamically typed language; you won't know if your code will work until you run it, but you're also working with Amazon's AWS SDK, it's derived from Java and expects a few things beyond just numbers and strings. In the end, you'd be beating your head against the stack traces and other `HTTP 400 - Bad Request` errors coming out of the S3 service. -**Is there anything that can help guarantee your calls to `upload` are legit with some sort of type checking?** +**Is there anything that can help guarantee your calls to `upload` are legit with some sort of type checking?** You've probably heard of the type annotated javascript superset language [TypeScript][typescript-site] and its supplementary type definition repository [Definitely Typed][dt-site], which contains definitions for many popular NPM packages including AWS-SDK. This would be great except switching from Javascript to TypeScript requires adoption from the rest of the team, separate `.ts` files, and modifications to your build process. Is there any way to get this without futzing with your existing project? If you're using the Visual Studio Code editor it turns out you can enable [type checking on a per-file basis][type-annotation] by adding the comment to the beginning of the file + ```javascript // @ts-check ``` -to the beginning of your file. + +to the beginning of your file.  The parameters variable is highlighted in red, and when you mouseover it you'll see: @@ -52,19 +53,20 @@ const parameters: { Body: string; } ``` -There are a bunch of things happening here! -It turns out VS Code has pulled in the AWS S3 type definitions in the background. The type of the parameter parameter that `s3.upload` takes is called `PutObjectRequest`. The Type Script compiler is kvetching over a missing required field it needs to say the `parameters` variable is of that type. There's nothing stopping you from running the code as it stands here, it'll just crash at runtime. +There are a bunch of things happening here! -When you add the `Key` parameter (the unique file key in an S3 bucket), the red squiggly underline disappears and you have a properly formed object. +It turns out VS Code has pulled in the AWS S3 type definitions in the background. The type of the parameter parameter that `s3.upload` takes is called `PutObjectRequest`. The Type Script compiler is kvetching over a missing required field it needs to say the `parameters` variable is of that type. There's nothing stopping you from running the code as it stands here, it'll just crash at runtime. +When you add the `Key` parameter (the unique file key in an S3 bucket), the red squiggly underline disappears and you have a properly formed object. The same checking is useful for output types. + ```javascript const { Location } = await s3.upload(parameters).promise(); ``` -You can mouseover s3.upload and see it returns a type of `AWS.S3.ManagedUpload.SendData`, which means the destructuring operation `{ Location }` is guaranteed to work and Location will be populated. +You can mouseover s3.upload and see it returns a type of `AWS.S3.ManagedUpload.SendData`, which means the destructuring operation `{ Location }` is guaranteed to work and Location will be populated. Links: @@ -75,9 +77,8 @@ JSDoc - the type annotation here is based after JSDoc, so looking at the docs ca `http://usejsdoc.org/tags-type.html` - More to come, as with introducing gradual typing, learning this stuff is also a gradual process that pays you back the more you put into it. [typescript-site]: https://www.typescriptlang.org/ [dt-site]: http://definitelytyped.org/ -[type-annotation]: https://github.com/Microsoft/TypeScript/wiki/Type-Checking-JavaScript-Files \ No newline at end of file +[type-annotation]: https://github.com/Microsoft/TypeScript/wiki/Type-Checking-JavaScript-Files diff --git a/_posts/2019-1-16-polyglot-setup.markdown b/blog/_posts/2019-1-16-polyglot-setup.markdown similarity index 100% rename from _posts/2019-1-16-polyglot-setup.markdown rename to blog/_posts/2019-1-16-polyglot-setup.markdown diff --git a/blog/_posts/2025-2-9-poor-mans-audiobook-reader.markdown b/blog/_posts/2025-2-9-poor-mans-audiobook-reader.markdown new file mode 100644 index 0000000..623e2ca --- /dev/null +++ b/blog/_posts/2025-2-9-poor-mans-audiobook-reader.markdown @@ -0,0 +1,72 @@ +--- +layout: post +title: "Poor Man's Audiobook Reader" +date: 2025-02-09T18:04:18.692Z +categories: posts +--- + +I'm currently reading a contemporary history of Steve Jobs's time with the creation and unraveling of NeXT Computer - [Steve Jobs and the NeXT Big Thing](Page not found :(
+The requested page could not be found.
+Iām a software dev with Go, Javascript and C#. Iām writing this blog to better at writing and to document my explorations.
diff --git a/docs/assets/css/main.css b/docs/assets/css/main.css new file mode 100644 index 0000000..d55c7ed --- /dev/null +++ b/docs/assets/css/main.css @@ -0,0 +1,3 @@ +html{height:100%}body{font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-size:1.0rem;line-height:2;margin:0;min-height:100%}h2,h3,h4,h5{margin-top:1.5em}hr{margin:1em 0}hr.page-break{text-align:center;border:0}hr.page-break:before{content:'-----'}hr.page-break:after{content:attr(data-content) "-----"}p{margin:1em 0}li{margin:0.4em 0}.w{max-width:720px;margin:0 auto;padding:4em 2em}table,th,td{width:100%;border:thin solid black;border-collapse:collapse;padding:0.4em}div.highlighter-rouge code,code.highlighter-rouge{display:block;overflow-x:auto;padding:1em}blockquote{font-style:italic;border:thin solid black;padding:1em}blockquote p{margin:0}img{max-width:100%;display:block;margin:0 auto}html{--bg: #FFF;--bg-secondary: #F8F9FA;--headings: #000;--text: #333;--links: blue;--highlight: #FFECB2}html[data-theme="dark"] html,html[data-theme="dark"] body{--headings: #74c0fc;--links: #91A7FF;--highlight: #41C7C7;--bg: #1f242A;--bg-secondary: #323945;--text: #adb5bd}@media (prefers-color-scheme: dark){body[data-theme="auto"] html,body[data-theme="auto"] body{--headings: #74c0fc;--links: #91A7FF;--highlight: #41C7C7;--bg: #1f242A;--bg-secondary: #323945;--text: #adb5bd}}html,body{background-color:var(--bg);color:var(--text)}h1,h2,h3,h4,h5,h6{color:var(--headings)}p,strong,b,em,small,li,hr,table,code,figcaption{color:var(--text)}code,blockquote{background-color:var(--bg-secondary);border:1px var(--text) solid}a{color:var(--links)}*:target{background-color:var(--bg-secondary)}html.transition,html.transition *,html.transition *:before,html.transition *:after{transition:all 250ms !important;transition-delay:0 !important}.theme-toggle{color:var(--text);background-color:transparent;padding:4px;cursor:pointer;margin:1em;position:fixed;right:0;top:0;border:2px transparent solid;outline:none}.theme-toggle:hover{color:var(--links);outline:none}.theme-toggle:focus{outline:none}.dashed{border-top:1px var(--text) dashed;margin:0.5em 0}mark{padding:0.4em;background-color:var(--highlight);font-size:0.7em}.post-date{color:var(--headings);margin-right:2em}.share{color:var(--text)}.home-date{font-family:monospace}.post-list-item a{text-decoration:none}.text-bold{font-weight:bold}.text-upcase{text-transform:uppercase}ul.horizontal-list{display:flex;margin-top:0em;margin-left:-40px;flex-wrap:wrap}ul.horizontal-list li{display:inline;margin-right:1em}ul.horizontal-list li a{text-decoration:none;font-weight:normal}.card{padding:1em;border:1px var(--text) solid;width:11em;height:11em;text-align:center;font-size:1em;align-items:center;background-color:var(--bg-secondary);margin-bottom:0.8em}.card .header{color:var(--links)}.card .body{font-size:0.8em}.card hr{margin:0.5em 0}@media screen and (max-width: 600px){ul.horizontal-list li.card{width:100%;display:block;margin-bottom:1em;margin-left:1em}ul.horizontal-list li.card a,ul.horizontal-list li.card .header{font-size:1em}} + +/*# sourceMappingURL=main.css.map */ \ No newline at end of file diff --git a/docs/assets/css/main.css.map b/docs/assets/css/main.css.map new file mode 100644 index 0000000..3633e19 --- /dev/null +++ b/docs/assets/css/main.css.map @@ -0,0 +1,16 @@ +{ + "version": 3, + "file": "main.css", + "sources": [ + "main.scss", + "../usr/local/bundle/gems/moonwalk-0.0.2/_sass/moonwalk.scss", + "../usr/local/bundle/gems/moonwalk-0.0.2/_sass/list.scss" + ], + "sourcesContent": [ + "@import \"moonwalk\";\n@import \"list\";\n", + "html { height: 100%; }\n\nbody {\n font-family: -apple-system,system-ui,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif;\n font-size: 1.0rem;\n line-height: 2;\n margin: 0;\n min-height: 100%;\n}\n\nh2, h3, h4, h5 { margin-top: 1.5em; }\n\nhr { margin: 1em 0; }\n\nhr.page-break {\n text-align: center;\n border: 0;\n\n &:before { content: '-----' }\n &:after { content: attr(data-content) '-----' }\n}\n\np { margin: 1em 0; }\n\nli { margin: 0.4em 0; }\n\n.w {\n max-width: 720px;\n margin: 0 auto;\n padding: 4em 2em;\n}\n\ntable, th, td {\n width: 100%;\n border: thin solid black;\n border-collapse: collapse;\n padding: 0.4em;\n}\n\ndiv.highlighter-rouge code, code.highlighter-rouge {\n display: block;\n overflow-x: auto;\n padding: 1em;\n}\n\nblockquote {\n font-style: italic;\n border: thin solid black;\n padding: 1em;\n\n p { margin: 0; }\n}\n\nimg {\n max-width: 100%;\n display: block;\n margin: 0 auto;\n}\nhtml {\n --bg: #FFF;\n --bg-secondary: #F8F9FA;\n --headings: #000;\n --text: #333;\n --links: blue;\n //--highlight: #FFD19B;\n --highlight: #FFECB2; // light yellow\n}\n// -------------- THEME SWITCHER -------------- //\n@mixin dark-appearance {\n html, body {\n --headings: #74c0fc;\n --links: #91A7FF;\n --highlight: #41C7C7;\n --bg: #1f242A;\n --bg-secondary: #323945;\n --text: #adb5bd;\n };\n}\nhtml[data-theme=\"dark\"] { @include dark-appearance; }\n\n@media (prefers-color-scheme: dark) {\n body[data-theme=\"auto\"] { @include dark-appearance; }\n}\n// -------------------------------------------- //\n\nhtml, body {\n background-color: var(--bg);\n color: var(--text);\n}\nh1, h2, h3, h4, h5, h6 {\n color: var(--headings);\n}\np, strong, b, em, small, li, hr, table, code, figcaption {\n color: var(--text);\n}\ncode, blockquote {\n background-color: var(--bg-secondary);\n border: 1px var(--text) solid;\n}\na {\n color: var(--links);\n}\n*:target { background-color: var(--bg-secondary); }\n\nhtml.transition,\nhtml.transition *,\nhtml.transition *:before,\nhtml.transition *:after {\n transition: all 250ms !important;\n transition-delay: 0 !important;\n}\n\n.theme-toggle {\n color: var(--text);\n background-color: transparent;\n padding: 4px;\n cursor: pointer;\n margin: 1em;\n position: fixed;\n right: 0;\n top: 0;\n border: 2px transparent solid;\n outline: none;\n}\n\n.theme-toggle:hover {\n color: var(--links);\n outline: none;\n}\n.theme-toggle:focus {\n outline: none;\n}\n.dashed {\n border-top: 1px var(--text) dashed;\n margin: 0.5em 0;\n}\nmark {\n padding: 0.4em;\n background-color: var(--highlight);\n font-size: 0.7em;\n}\n\n.post-date {\n color: var(--headings);\n margin-right: 2em;\n}\n.share {\n color: var(--text);\n}\n.home-date {\n font-family: monospace;\n}\n.post-list-item a {\n text-decoration: none;\n}\n.text-bold {\n font-weight: bold;\n}\n.text-upcase {\n text-transform: uppercase;\n}\n", + "ul.horizontal-list {\n display: flex;\n //justify-content: space-between;\n margin-top: 0em;\n margin-left: -40px;\n flex-wrap: wrap;\n\n li {\n display:inline;\n margin-right: 1em;\n }\n\n li a {\n text-decoration: none;\n font-weight: normal\n }\n\n}\n\n.card {\n padding: 1em;\n border: 1px var(--text) solid;\n width: 11em;\n height: 11em;\n text-align: center;\n font-size: 1em;\n align-items: center;\n background-color: var(--bg-secondary);\n margin-bottom: 0.8em;\n\n .header {\n color: var(--links);\n }\n\n .body {\n font-size: 0.8em;\n }\n\n hr {\n margin: 0.5em 0;\n }\n\n}\n\n/* Responsive cards - one column layout on small screens */\n@media screen and (max-width: 600px) {\n ul.horizontal-list li.card {\n width: 100%;\n display: block;\n margin-bottom: 1em;\n margin-left: 1em;\n a, .header {\n font-size: 1em;\n }\n }\n}\n" + ], + "names": [], + "mappings": "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" +} \ No newline at end of file diff --git a/docs/feed.xml b/docs/feed.xml new file mode 100644 index 0000000..89e23fe --- /dev/null +++ b/docs/feed.xml @@ -0,0 +1,349 @@ +got some downtime so how's about we starts ourselves a blog ...
+ +I like to play around with lots of different programming languages, but install too many and they pollute your working environment, so itās better to have them installed as a user instead of root.
+Hereās a way to get several of them installed into your unix user directory.
+If things go wrong, or you get bored you can easily rm -rf the installation.
Letās get ourselves a minimal debian environment. Iām using docker here, but you can use a native install, or a VM, or Windows Services for Linux with the ubuntu install.
+john@BigBox:~/git/JohnCSimon.github.io$ sudo docker run -ti debian /bin/bash
+Unable to find image 'debian:latest' locally
+latest: Pulling from library/debian
+cd8eada9c7bb: Pull complete
+Digest: sha256:58a80e0b6aa4d960ee2a5452b0230c406c47ed30a66555ba753c8e1710a434f5
+Status: Downloaded newer image for debian:latest
+root@6d933dddbbcd:/#
+Just to satisfy my OCD letās get the latest updates.
+ +apt update && apt upgrade -y
apt install gnupg2 curl procps -y
+ Installs gpg2, curl and ps
gpg2 --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
\curl -sSL https://get.rvm.io | bash -s stable
To start using RVM you need to run source /etc/profile.d/rvm.sh or re-login to re-load ~/.profile
From here you can run - rvm list known and youāll see a list of ruby flavors and individual versions.
# MRI Rubies
+[ruby-]1.8.6[-p420]
+[ruby-]1.8.7[-head] # security released on head
+[ruby-]1.9.1[-p431]
+[ruby-]1.9.2[-p330]
+[ruby-]1.9.3[-p551]
+[ruby-]2.0.0[-p648]
+[ruby-]2.1[.10]
+[ruby-]2.2[.10]
+[ruby-]2.3[.8]
+[ruby-]2.4[.5]
+[ruby-]2.5[.3]
+[ruby-]2.6[.0]
+MRI Ruby is the reference version of Ruby so letās install the latest version.
+ +rvm install ruby-2.6.0
Iām running debian and rvm might ask for your root password to install some prerequsites from apt before compiling a new version.
+ +Congrats, you now have a ruby install
+ +$ ruby -v
+ruby 2.6.0p0 (2018-12-25 revision 66547) [x86_64-linux]
+from here you can now do whatever since Iām blogging this using jekyll
+ +gem install bundler jekyll
Go is a language that releases new versions on a regular basis.
+Thereās a similar tool to rvm called gvm. Itās a āgo version managerā available from here https://github.com/moovweb/gvm thatāll let you install multiple versions and set $GOPATH and $GOROOT.
as a regular user:
+$ bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
+Cloning from https://github.com/moovweb/gvm.git to /root/.gvm
+No existing Go versions detected
+Installed GVM v1.0.22
+
+Please restart your terminal session or to get started right away run
+ `source /root/.gvm/scripts/gvm`
+you should be able to run and see
+$ gvm version
+Go Version Manager v1.0.22 installed at /home/john/.gvm
+Run gvm listall
+which will give you a list of all the available versions of go.
$gvm listall
+
+gvm gos (available)
+
+ go1
+ go1.0.1
+ ...
+ go1.11rc1
+ go1.11rc2
+ go1.11.1
+ go1.11.2
+ go1.11.3
+ go1.11.4
+ go1.12beta1
+ go1.12beta2
+of which there are entirely too many.
+ +From here, we can install go as our user via binary here:
+ +gvm install go1.4 -B
try it out
+$ go version
+go version go1.4 linux/amd64
+We can see it gets installed here:
+$ echo $GOROOT
+/home/john/.gvm/gos/go1.4
+From the gvm link earlier, in order to compile a go build environment for versions 1.5 on we require another go build environment. +Go compiles itself! Neat huh?
+ +As of now the latest version is go1.11.4
+$ export GOROOT_BOOTSTRAP=$GOROOT
+$ gvm install go1.11.4
+$ go version
+go version go1.4 linux/amd64
+you can run
+gvm use - select a go version to use (--default to set permanently)
$ gvm use go1.11.4 --default
+Now using version go1.11.4
+$ go version
+go version go1.11.4 linux/amd64
+$ echo $GOROOT
+/home/john/.gvm/gos/go1.11.4
+$ echo $GOPATH
+/home/john/.gvm/pkgsets/go1.11.4/global
+$ ls /home/john/.gvm/gos/go1.11.4
+AUTHORS CONTRIBUTING.md CONTRIBUTORS LICENSE PATENTS README.md VERSION api bin doc favicon.ico lib manifest misc pkg robots.txt src test
+ls $GOPATH
+overlay pkg src
+Be sure to set ādefault so you keep the same version when you relaunch the shell, so that whatever you install stays where you expect it.
+ +node.js, the server side javascript framework
+ +nvm is Node Version Manager. Install it like this:
+curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
Since there are major revisions to the javascript language between node 4, 6, 8 Iāve found Iāve had to switch more often between these versions according to project than I did with other languages.
+ +You can run nvm ls-remote and get a list of all the node versions available
$ nvm
+Example:
+ nvm install 8.0.0 Install a specific version number
+ nvm use 8.0 Use the latest available 8.0.x release
+ nvm run 6.10.3 app.js Run app.js using node 6.10.3
+ nvm exec 4.8.3 node app.js Run `node app.js` with the PATH pointing to node 4.8.3
+ nvm alias default 8.1.0 Set default node version on a shell
+ nvm alias default node Always default to the latest available node version on a shell
+so if you run
+ +$ nvm install 10
+Downloading and installing node v10.15.0...
+Downloading https://nodejs.org/dist/v10.15.0/node-v10.15.0-linux-x64.tar.gz...
+######################################################################## 100.0%
+Computing checksum with sha256sum
+Checksums matched!
+Now using node v10.15.0 (npm v6.4.1)
+Creating default alias: default -> 10 (-> v10.15.0)
+
+$ whereis node
+node: /home/john/.nvm/versions/node/v10.15.0/bin/node
+and you can set it to be the default so the setting persists between sessions
+nvm alias default 10
+So now you can run:
+$ node -v
+v10.15.0
+$ npm -v
+6.4.1
+Rust is another language that sees regular updates. Youāll just have to check which is the version for the 2015 and 2018 edition.
+ +curl https://sh.rustup.rs -sSf | sh
+
+
+
+Current installation options:
+
+ default host triple: x86_64-unknown-linux-gnu
+ default toolchain: stable
+ modify PATH variable: yes
+
+1) Proceed with installation (default)
+2) Customize installation
+3) Cancel installation
+>
+
+select 1
+
+To configure your current shell run source $HOME/.cargo/env
+add $HOME/.cargo/env to your path in .bashrc
$ whereis cargo
+cargo: /home/john/.cargo/bin/cargo
+$ whereis rustc
+cargo: /home/john/.cargo/bin/rustc
+Recently I had to write a file uploader for AWS S3 in node.
+ +
+const AWS = require('aws-sdk');
+const s3 = new AWS.S3({ signatureVersion: 'v4' });
+
+const uploadToS3 = async () => {
+ const parameters = {
+ Bucket: s3Bucket,
+ Body: fileData,
+ };
+
+ try {
+ const { Location } = await s3.upload(parameters).promise();
+ return Location;
+ } catch (e) {
+ process.exit(1);
+ }
+};
+It looks simple enough, but youāre probably going to be spending a decent amount of time googling around for examples if the parameters in an s3 call are more than just basic hello world. Add to this javascript is a dynamically typed language; you wonāt know if your code will work until you run it, but youāre also working with Amazonās AWS SDK, itās derived from Java and expects a few things beyond just numbers and strings. In the end, youād be beating your head against the stack traces and other HTTP 400 - Bad Request errors coming out of the S3 service.
Is there anything that can help guarantee your calls to upload are legit with some sort of type checking?
Youāve probably heard of the type annotated javascript superset language TypeScript and its supplementary type definition repository Definitely Typed, which contains definitions for many popular NPM packages including AWS-SDK. This would be great except switching from Javascript to TypeScript requires adoption from the rest of the team, separate .ts files, and modifications to your build process. Is there any way to get this without futzing with your existing project?
If youāre using the Visual Studio Code editor it turns out you can enable type checking on a per-file basis by adding the comment to the beginning of the file
+ +// @ts-check
+to the beginning of your file.
+
The parameters variable is highlighted in red, and when you mouseover it youāll see:
+ +Argument of type '{ Bucket: string; Body: string; }' is not assignable to parameter of type 'PutObjectRequest'.
+ Property 'Key' is missing in type '{ Bucket: string; Body: string; }' but required in type 'PutObjectRequest'.ts(2345)
+s3.d.ts(3640, 5): 'Key' is declared here.
+const parameters: {
+ Bucket: string;
+ Body: string;
+}
+There are a bunch of things happening here!
+ +It turns out VS Code has pulled in the AWS S3 type definitions in the background. The type of the parameter parameter that s3.upload takes is called PutObjectRequest. The Type Script compiler is kvetching over a missing required field it needs to say the parameters variable is of that type. Thereās nothing stopping you from running the code as it stands here, itāll just crash at runtime.
When you add the Key parameter (the unique file key in an S3 bucket), the red squiggly underline disappears and you have a properly formed object.
The same checking is useful for output types.
+ + const { Location } = await s3.upload(parameters).promise();
+You can mouseover s3.upload and see it returns a type of AWS.S3.ManagedUpload.SendData, which means the destructuring operation { Location } is guaranteed to work and Location will be populated.
Links:
+ +Type Annotation and Checking within javascript
+ https://github.com/Microsoft/TypeScript/wiki/Type-Checking-JavaScript-Files
JSDoc - the type annotation here is based after JSDoc, so looking at the docs canāt hurt
+ +http://usejsdoc.org/tags-type.html
More to come, as with introducing gradual typing, learning this stuff is also a gradual process that pays you back the more you put into it.
+ + + + + +Iām currently reading a contemporary history of Steve Jobsās time with the creation and unraveling of NeXT Computer - Steve Jobs and the NeXT Big Thing.
+
Today, popular culture paints him as an iconic figure, but when the book was written in 1993 NeXT was a money pit, only kept alive with cash infusions from outside investors as money was burnt. Itās a wild ride, I highly recommend it, especially with hindsight.
+ +Unfortunately, reading books cover to cover is hard for me. I rely on audiobooks so I can ride the bus or do dishes while I absorb a book. Unfortunately, there is no audiobook release of this book.
+ +I found the book in PDF form on archive.org. Unfortunately PDFs are more of a page layout language like HTML instead of a store of text.
+ +If you were to use Text to Speech functionality say - speak visible content on your PC or phone on a typical website or PDF you have to ābaby sitā what is being read so that the reader doesnāt get ālostā or get caught up on footnotes or stop abruptly or be unable to handle a change in fonts. Itās not obvious how broken this functionality is.
+ +
Plain text is the best for a text to speech program. Luckily, archive.org provides a plain text version of the book which was created via optical character recognition (see the archive.org site). Short of a few footnotes, itās 95% of what we need.
+ +Except⦠text to speech generation is a high CPU task, Apple iOS doesnāt like long running tasks. You canāt scrub back and forth within a document like you can with an audio book or video. Also, it seems that this functionality within iOS doesnāt see as much development as other parts of the OS, itās generally a janky experience more optimized for the vision impaired than my use case.
+ +So, we need an offline bulk text to speech generator. Luckily, macOS provides just the very thing hidden as one of the command line utilities - this is the say utility say -v Bad\ News "Captain, you are needed on the bridge" -w 200 but it can take additional parameters (see the man pages āman sayā )
example call:
+ +say --voice=Ava \ # use '?' to get a list of all the available voices
+ --input-file Steve_Jobs_\&_the_NeXT_Big_Thing_1993_djvu.txt \ # path to plain text file
+ --data-format=m4b \ # File for the output format, m4b is the apple's audiobook equavalent of m4a see 'say --file-format='?' ' for the list of these
+ --output-file=MyOutputFile.m4b \ # output file
+ --rate=150 # speaking rate in words per minute, to your taste.
+ --progress # print the progress
+This is awesome! But after letting it run for one later the CPU is still at 100% and the process is consuming 2.3 GB of RAM and the output file MyOutoutFile.m4b is about 50 MB on disk.
+ +Something is up ⦠letās see the word count of this file.
+ +wc -lw Steve_Jobs_\&_the_NeXT_Big_Thing_1993_djvu.txt
+14908 122808 Steve_Jobs_&_the_NeXT_Big_Thing_1993_djvu.txt
+so 15000 lines, 122000 words - at 150 words / minute this is about 13 hours to read through all of it, and an audiobook of that length is roughly 1 GB.
+ +Maybe the compression or some other non-default setting is mucking with this? I remove everything except the input and output files parameters and I still see the same poor performnace.
+ +Letās break this down into 1000 line chunks, and feed each one to say.
+ +split -d -l 1000 Steve_Jobs_\&_the_NeXT_Big_Thing_1993_djvu.txt Steve1000__
+time for file in Steve1000__*; do time say \
+ -f "$file" \
+ -o "$file.m4b" \
+ --file-format=m4bf \
+ --rate=150 \
+ --progress; done
+Well thatās interesting, the process completed in 10 minutes and produced 14 files that comprise the audio book.
+ +But, I donāt want 14 parts, Iād like, say, three parts of 5000 lines each. I re-run the script ā¦
+split -d -l 5000 Steve_Jobs_\&_the_NeXT_Big_Thing_1993_djvu.txt Steve5000__
And each part takes 30 minutes to generate, a total of 90 minutes of CPU time.
+ +Intuitively, generating voice from a text file would be a linear operation. Text goes in, Audio goes out, no doubling back through a stream. But, thereās clearly a bug in the implementation of say that makes the run time be something larger than O(n^2). Apparently having say spew out hours of audio for an entire book was never a tested use case. Except, say has been around for as long as MacOSX has been around, one would think all the bugs have been worked out. Apparently not; you have to test and test and test, there will always be surprises.
+ + + + +