979Batch Rename Files with rename

Batch renaming files on the command line, in this case screenshot to more descriptive names:

brew install rename

Dry run:

rename -n -e 's/Screen Shot/w2_OpenSCAD/' -z  *.jpg

Replace, remove the -n flag:

rename -e 's/Screen Shot/w2_OpenSCAD/' -z  *.jpg

-z does sanitize the file name, replacing empty spaces with _.

978Changing default Screenshot Form in OSX

Default format is PNG, change it to any of the following:

defaults write com.apple.screencapture type JPG
defaults write com.apple.screencapture type TIFF
defaults write com.apple.screencapture type GIF
defaults write com.apple.screencapture type PDF
defaults write com.apple.screencapture type PNG

First encountered here.

976Git, Mac, SSH Keys and the OSX Keychain

When using git with a key that has a passphrase, you are asked the passphrase every time you pull/push. To make this a bit more convenient, add the key to the OSX Keychain.

Store key in OSX Keychain:

ssh-add -K ~/.ssh/my_key

Open .ssh/config

Host *
  UseKeychain yes
  AddKeysToAgent yes
  IdentityFile ~/.ssh/my_key

973Create a Password-Protected Zip

zip -er test.zip MyFiles

From man zip

-e
--encrypt

Encrypt the contents of the zip archive using a password which is entered on the terminal in response to a prompt (this will not be echoed; if standard error is not a tty, zip will exit with an error).  The password prompt is repeated to save the user from typing errors.

-r
--recurse-paths
Travel the directory structure recursively

-P
--password password
Use password to encrypt zipfile entries (if any).  THIS IS INSECURE!

zip -er -P mypassword test.zip myFiles

971ScrollTo, Vue and Vue-Router

After navigating to a certain page - let's call it Chat, it want to scroll programmatically to the bottom of the page. In pure JS it would look like this:

window.scrollTo(0,document.body.scrollHeight);

Which words fine - but it does not work after Vue-Router changes. For that to work, the rounter config needs to be changed:

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes,
  scrollBehavior (to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition
    } else if (to.name === 'Chat'){
      return { x: 0, y: window.innerHeight }
    }
    return false
  }
})

If a savedPosition exist (in case of back/forward navigation with browser buttons), return that saved position, if the page is called Chat, then scroll y to the window.innerHeight.

970Parsing Body JSON for quick inspection

An API dumps its output as string in the HTML body. Not really much use, not really easy to inspect it. The solutions? Parse the body with JSON.parse an inspect it in the console.

JSON.parse(document.body.textContent)
[{"id":115,"date":"2020-11-09T02:57:48","date_gmt":"2020-11-09T02:57:48","guid":{"rendered":"http:\/\/127.0.0.1\/aaa\/?
post_type=jobs&p=115"},"modified":"2020-11-09T05:22:55","modified_gmt":"2020-11-09T05:22:55","slug":"another-test-
job","status":"publish","type":"jobs","link":"http:\/\/127.0.0.1\/aaa\/jobs\/another-test-job\/","title":{"rendered":"Another Test 
Job"},"parent":0,"menu_order":0,"template":"","_links":{"self":[{"href":"http:\/\/127.0.0.1\/aaa\/wp-
json\/wp\/v2\/jobs\/115"}],"collection":[{"href":"http:\/\/127.0.0.1\/aaa\/wp-json\/wp\/v2\/jobs"}],"about":
[{"href":"http:\/\/127.0.0.1\/aaa\/wp-json\/wp\/v2\/types\/jobs"}],"wp:attachment":[{"href":"http:\/\/127.0.0.1\/aaa\/wp-
json\/wp\/v2\/media?parent=115"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}},
{"id":96,"date":"2020-11-09T02:48:51","date_gmt":"2020-11-09T02:48:51","guid":{"rendered":"http:\/\/127.0.0.1\/aaa\/?
post_type=jobs&p=96"},"modified":"2020-11-09T05:23:30","modified_gmt":"2020-11-09T05:23:30","slug":"test-
job","status":"publish","type":"jobs","link":"http:\/\/127.0.0.1\/aaa\/jobs\/test-job\/","title":{"rendered":"Test 
Job"},"parent":0,"menu_order":0,"template":"","_links":{"self":[{"href":"http:\/\/127.0.0.1\/aaa\/wp-
json\/wp\/v2\/jobs\/96"}],"collection":[{"href":"http:\/\/127.0.0.1\/aaa\/wp-json\/wp\/v2\/jobs"}],"about":
[{"href":"http:\/\/127.0.0.1\/aaa\/wp-json\/wp\/v2\/types\/jobs"}],"wp:attachment":[{"href":"http:\/\/127.0.0.1\/aaa\/wp-
json\/wp\/v2\/media?parent=96"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}]

968Clean Vue Distribution Files

Removing the timestamp from css and js distribution files.
File: vue.config.js

module.exports = {
  publicPath: '',
  chainWebpack: config => {
    if(config.plugins.has('extract-css')) {
      const extractCSSPlugin = config.plugin('extract-css')
      extractCSSPlugin && extractCSSPlugin.tap(() => [{
        filename: 'css/[name].css',
        chunkFilename: 'css/[name].css'
      }])
    }
  },
  configureWebpack: {
    output: {
      filename: 'js/[name].js',
      chunkFilename: 'js/[name].js'
    }
  }
}

966Combining JSON files in Python

Quick python script to combine several JSON files into one. File names are dict keys in the JSON output.

import os
import json

entries = os.listdir(os.getcwd())

animationFiles = [
  'aaa',
  'bbb',
  'ccc'
]

output = {}

for name in animationFiles:
  with open(name + '.json') as f:
    output[name] = json.loads(f.read())

outputFile = open('output.json', 'w')
outputFile.write( json.dumps(output) )

print('Done')

964Gettting HTML Content from index.html into Vue

Vue index.html:

  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
    <div id="modalContent" style="display:none">
      <div id="modal1">
        Hello Modal Content Hello Modal Content
      </div>
    </div>
  </body>

Why add another hidden div to index.html? To be able to edit/add content without rebuilding and running npm run build.

In Vue:

  document.getElementById('modal1').innerHTML

Actually basic JS, nothing special to Vue.

963General JS Variables in Vue

Accesses JS from outside Vue:

index.html

...
<script>
  var test = "test";
</script>
...

In Vue:

  window.test

Obvious, but nevertheless