How to add JS Drag-&-Drop file upload without any dependencies

Problem:

For your new web application, you want to add drag&drop file uploads without using any external library.

Solution:

You can use this set of functions, which you can adapt to your application.

/**
 * Initialize drag & drop event handling for a DOM element.
 * The DOM element does not have to be empty in order to do this.
 * @param elem The DOM element where files can be dragged & dropped
 * @param callback The callback(files) function that gets passed a list of files
 * when files are dragged and dropped.
 *
 * Basic usage example:
 *  var elem = document.getElementById('mydiv');
 *  initializeDragAndDrop(elem, function(files) {
 *      for (var i = 0; i < files.length; i++) {
 *          // Do something with files[i]...
 *          handleUploadedFile(files[i]); // Replace by your code
 *      }
 *  });
 */
function initializeDragAndDrop (elem, callback) {
    elem.addEventListener('drop', function (event) {
        _dragndrop_preventDefault(event);
        callback(event.dataTransfer.files);
    }, false);
    elem.addEventListener('dragover', _dragndrop_preventDefault, false);
    elem.addEventListener('dragdrop', _dragndrop_preventDefault, false);
    elem.addEventListener('dragenter', _dragndrop_preventDefault, false);
    elem.addEventListener('dragleave', _dragndrop_preventDefault, false);
}

/**
 * Internal utility function to prevent default
 * handling for a given event.
 */
function _dragndrop_preventDefault (event) {
    event.stopPropagation();
    event.preventDefault();
}

Usage example:

var elem = document.getElementById('mydiv');
initializeDragAndDrop(elem, function(files) {
    for (var i = 0; i < files.length; i++) {
        // Do something with files[i]...
        handleUploadedFile(files[i]); // Replace by your code
    }
});

Note that you need to run initializeDragAndDrop only after the respective DOM element (mydiv in this example) has been loaded. For example, you could call it like this if you use jQuery:

$(document).ready(function() {
    initializeDragAndDrop(/* ... */);
});

Pure Javascript (no jQuery):

// WARNING: This will replace any window.onload function
// that is currently set.
// Also, this will only fire after everything on the page
// has been loaded, which might not be the desired behaviour.
window.onload = function() {
    initializeDragAndDrop(/* ... */);
};

Also see this previous TechOverflow post on how to read the uploaded files into memory, if you need to.

Reading an uploaded file into memory using pure Javascript

You have a File object in Javascript (e.g. from a drag & drop upload or a <input type="file">) which you want to read into memory in the browser. You don’t want to use any library to do that but prefer a pure Javascript solution.

Solution:

Use this function:

/**
 * Utility function to read an entire file into memory.
 *
 * The handler function gets passed an array of objects:
 * {
 *     name: filename as string,
 *     size: size in bytes as number,
 *     type: MIME type as string,
 *     content: file content as Uint8Array
 * }
 * @param file The file to read
 * @param handler
 */
function readFileIntoMemory (file, callback) {
    var reader = new FileReader();
    reader.onload = function () {
        callback({
            name: file.name,
            size: file.size,
            type: file.type,
            content: new Uint8Array(this.result)
         });
    };
    reader.readAsArrayBuffer(file);
}

Usage example:

// Usage example
readFileIntoMemory(file, function(fileInfo) {
    console.info("Read file " + fileInfo.name + " of size " + fileInfo.size);
    // You can use fileInfo.content, which is a Uint8Array, here
});

Copying strings to the clipboard using pure Javascript

You want to copy a string to the system clipboard in the browser without using any dependency like clipboard.js .

Solution:

Use this function:

function copyStringToClipboard (str) {
   // Create new element
   var el = document.createElement('textarea');
   // Set value (string to be copied)
   el.value = str;
   // Set non-editable to avoid focus and move outside of view
   el.setAttribute('readonly', '');
   el.style = {position: 'absolute', left: '-9999px'};
   document.body.appendChild(el);
   // Select text inside element
   el.select();
   // Copy text to clipboard
   document.execCommand('copy');
   // Remove temporary element
   document.body.removeChild(el);
}

Note: If the user selected anything when you ran the function, this selection will be cleared. If you need to preserve the selection, see this Hackernoon article for a more elaborate solution..

You can use it like this:

// Usage example:
copyStringToClipboard("abc123");

It works by adding a temporary <textarea> element onto the DOM which is moved outside (credits to Angelos Charalis on Hackernoon for the original idea) the viewport in order to avoid wreaking havoc on screenreaders etc.

ISO8601 UTC time as std::string using C++11 chrono

You want to use the C++11 standard’s chrono library to generate a ISO8601-formatted timestamp as a std::string, e.g. 2018-03-30T16:51:00Z

Solution:

You can use this function which uses std::put_time with a std::ostringstream to generate the resulting std::string.

#include <iostream>
#include <chrono>
#include <iomanip>
#include <sstream>

/**
 * Generate a UTC ISO8601-formatted timestamp
 * and return as std::string
 */
std::string currentISO8601TimeUTC() {
  auto now = std::chrono::system_clock::now();
  auto itt = std::chrono::system_clock::to_time_t(now);

  std::ostringstream ss;
  ss << std::put_time(gmtime(&itt), "%FT%TZ");
  return ss.str();
}

// Usage example
int main() {
    std::cout << currentISO8601TimeUTC() << std::endl;
}

 

How to fix NodeJS request Error: Argument error, options.body

Problem:

You’re using request to send a POST request with a body that should be JSON-encoded, but you are encountering an error similar to this:

Error: Argument error, options.body.
    at setContentLength (/home/uli/myproj/node_modules/request/request.js:434:28)
    at Request.init (/home/uli/myproj/node_modules/request/request.js:439:5)
    at new Request (/home/uli/myproj/node_modules/request/request.js:128:8)
    at request (/home/uli/myproj/node_modules/request/index.js:53:10)
    at Function.post (/home/uli/myproj/node_modules/request/index.js:61:12)

and, additionally this stacktrace:

TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be one of type string or Buffer
    at write_ (_http_outgoing.js:647:11)
    at ClientRequest.write (_http_outgoing.js:622:10)
    at Request.write (/home/uli/myproj/node_modules/request/request.js:1501:27)
    at end (/home/uli/myproj/node_modules/request/request.js:546:18)
    at Immediate.<anonymous> (/home/uli/myproj/node_modules/request/request.js:575:7)
    at runCallback (timers.js:763:18)
    at tryOnImmediate (timers.js:734:5)
    at processImmediate (timers.js:716:5)

Solution:

The error basically tells you that request can’t determine the length of the body, as you didn’t tell it how to encode the body and it isn’t a simple string or buffer. The solution is to tell request to use JSON body encoding by adding json: true to the options parameter (first argument to request.post). A valid options parameter looks like this:

const opts = {
    url: 'http://localhost:1234/api/myapi',
    body: {/* your body object */},
    json: true // <-- Add this line
};

How to use BIOS instead of UEFI firmware for a VMWare virtual machine

Recent versions of VMWare’s VMPlayer use UEFI firmwares by default if you select a UEFI-compatible operating system during VM creation.
There are some cases, however, in which you have to change the VM to a classical BIOS firmware afterwards, for example if you have your operating system installed without UEFI support or if you selected the wrong operating system.

Currently, it seems to be impossible do change the firmware setting in the GUI, therefore you first have to find the .vmx file corresponding to the virtual machine. Usually it is located at ~/vmware/<Name of VM>/<Name of VM>.vmx.

After stopping the VM , open that file in your favourite text editor and look for this line:

firmware = "efi"

Change it to

firmware = "bios"

After that, save the file, restart VMPlayer and start your VM.

How to delete the baloo index database file

baloo is a KDE desktop search component that indexes files in order to speed up the search.

The index can get quite large, e.g. my index consumes more than 2 GB of HDD space:

$ balooctl indexSize
Actual Size: 2,04 GiB
Expected Size: 1,33 GiB

           PostingDB:     313,32 MiB    22.924 %
         PosistionDB:     521,05 MiB    38.122 %
            DocTerms:     167,93 MiB    12.287 %
    DocFilenameTerms:      53,46 MiB     3.912 %
       DocXattrTerms:            0 B     0.000 %
              IdTree:       9,79 MiB     0.716 %
          IdFileName:      41,71 MiB     3.052 %
             DocTime:      25,80 MiB     1.887 %
             DocData:       2,02 MiB     0.148 %
   ContentIndexingDB:      14,86 MiB     1.087 %
         FailedIdsDB:            0 B     0.000 %
             MTimeDB:       9,12 MiB     0.667 %

If you don’t want to use baloo anyway or if you just want to re-index all files, you might want to delete the entire index:

rm -rf ~/.local/share/baloo

Note that if you haven’t disabled baloo using balooctl stop ; balooctl disable it might silently re-create the index in the background.

How to fix KaTeX parse error: KaTeX doesn’t work in quirks mode

Problem:

You’re using KaTeX on a website, but every time you try to render, you encounter the following error message:

Uncaught Error: KaTeX parse error: KaTeX doesn't work in quirks mode.
    at new e (VM697 katex.min.js:1)
    at Object.l [as render] (VM697 katex.min.js:1)
[...]

Solution:

KaTeX requires a valid DOCTYPE declaration on your HTML page, so add this line at the top of your HTML file(s), above <html>

<!DOCTYPE html>

Thanks to @xymostech on GitHub for the original solution in the the KaTeX issue tracker:

Automated rendering of PDB proteins using PyMol

Downloading the .pdb file

As the RCSB offers direct HTTP acess, this step is trivial.

You can use this shell script to download any protein:

#!/bin/bash
# donwload-pdb.sh
wget http://www.rcsb.org/pdb/files/$1.pdb

Call it with the PDB ID to download, e.g. 1ULI:

./download-pdb.sh 1ULI

Rendering using PyMol

First, install PyMol: Either download it from the website or just use your preferred package manager, e.g.:

sudo apt-get install pymol

By calling PyMol with a script instead of in interactive mode, we can automate the process of rendering an image – manual tuning of the perspective etc is likely to improve the results, however.

The following script integrates both the automatic download and the renderer. A temporary .pml (PyMol script) file is created with static settings

#!/bin/bash
# render-pymol.sh
if [ $# -eq 0 ]
  then
    echo "Usage: render-pymol.sh <PDB ID>"
    exit
fi
#Download
wget -qO $1.pdb http://www.rcsb.org/pdb/files/$1.pdb

#Create the rasmol script
echo "load $1.pdb;" > $1.pml
echo "set ray_opaque_background, on;" >> $1.pml
echo "show cartoon;" >> $1.pml
echo "color purple, ss h;" >> $1.pml
echo "color yellow, ss s;" >> $1.pml
echo "ray 1500,1500;" >> $1.pml
echo "png $1.png;" >> $1.pml
echo "quit;" >> $1.pml

#Execute PyMol
pymol -qxci $1.pml
#Remove temporary files
rm -rf $1.pml $1.pdb

Call it like this:

./render-pymol.sh 1ULI

This command will render the result and store it in 1ULI.png

Customizing the render style

In order to change the size of the generated PNG image, change this line:

echo "ray 1500,1500;" >> $1.pml

The numbers represent the width and height of the generated image. Note that increasing the image size will significantly increase the CPU time required to render the image, especially for complex proteins. Running render-pymol.sh with 1500x1500px to render the 1ULI  took 209 seconds on my Notebook as opposed to 33 seconds for 500×500.

These lines define the style of the rendered protein:

echo "show cartoon;" >> $1.pml
echo "color purple, ss h;" >> $1.pml
echo "color yellow, ss s;" >> $1.pml

while this line set the background color to transparent:

echo "set ray_opaque_background, off;" >> $1.pml

If you prefer a white (non-transparent) background instead, you can add this line right after the line containing load $1.pdb:

echo "bg_color white;" >> $1.pml
echo "set ray_opaque_background, off;" >> $1.pml

Results

1ULI

3ULI

How to fix GCC error ‘the lambda has no capture-default’

When encountering a GCC error like this:

error: the lambda has no capture-default

fixing it is usually quite easy. Look for a Lambda function that captures some variable like this

[&myVar] (/* ... */) {/* ... */}

&myVar means “capture myVar by reference”.

In most cases you can just capture all local variables by using a capture default:

[&] (/* ... */) {/* ... */}

In rare cases this will have unintended side-effects as you now are capturing all variables by reference where you might want to capture some by copy – so be sure to check your code.

Note that this error is GCC version-dependent. For me using GCC 7.2 fixed the error.

How to fix Angular ‘TypeError: templateRef.createEmbeddedView is not a function’

Problem:

You encounter an error message like this:

ERROR TypeError: templateRef.createEmbeddedView is not a function
    at ViewContainerRef_.createEmbeddedView (core.js:11389)
    at NgIf._updateView (common.js:2843)
    at NgIf.set [as ngIfElse] (common.js:2815)
    at updateProp (core.js:12602)
    at checkAndUpdateDirectiveInline (core.js:12313)
    at checkAndUpdateNodeInline (core.js:13876)
    at checkAndUpdateNode (core.js:13819)
    at debugCheckAndUpdateNode (core.js:14712)
    at debugCheckDirectivesFn (core.js:14653)
    at Object.eval [as updateDirectives] (MyComponent.html:1)

in a component where you have a source code similar to this

<div *ngIf="myCondition ; else elseSection">
    <!-- ... -->
</div>
<div #elseSection>
    <!-- ... -->
</div>

Solution:

Whatever element you reference in the *ngIf else clause can’t be any arbitrary component, but it must be a ng-template.

In order to solve this, change <div #elseSection> to <ng-template #elseSection>. Note that using just <template> is deprecated since Angular4.

The resulting source code should look like this:

<div *ngIf="myCondition ; else elseSection">
    <!-- ... -->
</div>
<ng-template #elseSection>
    <!-- ... -->
</ng-template>

How to fix Angular ‘Cannot find control with unspecified name attribute’

Problem:

In your Angular2/4/5 application you see this error message:

Cannot find control with unspecified name attribute

Solution:

Look for a statement in the HTML angular template like this:

[formControl]="myCtrl"

The error message means that myCtrl can’t be found. Check if this variable is present in your class – it needs be a FormControl which you can import from @angular/forms:

import { FormControl } from '@angular/forms';

In my case, changing it to

[formControl]="myControl"

fixed the issue

How to fix Angular4/5/6 ‘No provider for ControlContainer’

Problem:

In your Angular2/4/5 application you’re getting the following error message:

No provider for ControlContainer ("<div class="recall-container mat-elevation-z8">

Solution:

You have not added the @angular/forms FormsModule to your module’s import list.

Go to your app.module.ts and add this line to the imports:

import { FormsModule } from '@angular/forms';

and look for a line like this in your module definition:

imports: [ /* several import modules may be listed here */ ],

and add FormsModule like this (if there are already imports, add FormsModule to the list):

imports: [ FormsModule ],

How to fix error TS2339: Property ‘userLanguage’ does not exist on type ‘Navigator’.

Problem:

When developing with typescript,  e.g. with Angular2, you get an error message similar to this one:

error TS2339: Property 'userLanguage' does not exist on type 'Navigator'.

Solution:

Check the error message for the correct file and line. Look for a statement like

window.navigator.userLanguage

Currently typescript does not have userLanguage as a property (tested with typescript up to 2.7.1), although it should already be fixed according to this issue.

You can work around this by simply replacing the statement listed above by

window.navigator['userLanguage']

Using this approach, Typescript will simply not check if the attribute is present or not.

Which version on CuDNN should you install for TensorFlow GPU on Ubuntu?

Problem:

You’ve followed my previous blogpost

Fixing TensorFlow libcublas.so.8.0: cannot open shared object file on Ubuntu

on how to install CuBLAS etc. in order to get TensorFlow working.

Now you are getting an error message similar to this:

ImportError: libcudnn.so.6: cannot open shared object file: No such file or directory

You are wondering how you can install CuDNN as it’s not available from your

Solution:

In order to install CuDNN, first go to the NVIDIA CuDNN page. At the time of writing this, downloading CuDNN is only possible if you have an NVIDIA account, so you need to register (click on Join) if you dont have one or Login if you already have one.

On the CuDNN download page you have several versions of CuDNN to choose from. Don’t just download the newest one as TensorFlow requires a specific one.

Look at your error message: It tells you that TensorFlow is missing libcudnn.so.6 – can you see the 6 in that string? That means that you need CuDNN 6.x(TensorFlow 1.5.0, at the time of writing this, always requires CuDNN 6.x). Although you can install CuDNN 7.x, 8.x, 9.x in parallel to 6.x,

Once you have selected the correct version, you need to select a package type.

The first important choice is whether you want a developer package or just the runtime package. You don’t need the developer package to run TensorFlow, even if you are developing applications using TensorFlow! Just select the runtime package.

Regarding the type of package, of course if you are on Linux, you absolutely need to select a linux package. If you use Ubuntu 16.04+, the easiest option is to select cuDNN v6.0 Runtime Library for Ubuntu16.04 (Deb) – even though the name suggest it supports only 16.04, this package worked flawlessly for me on Ubuntu 17.04 and 17.10 as well.

I recommend to download the Ubuntu 16.04 DEB package option unless you have a specific reason not to use it.

Converting namedtuples to XLSX in Python

This Python snippet allows you to convert an iterable of namedtuple instances to an XLSX file using xlsxwriter.

The header is automatically determined from the first element of the iterable. If the iterable is empty, the resulting XLSX file will also be empty.

import xlsxwriter
import itertools
from collections import namedtuple

def xlsx_write_rows(filename, rows):
    """
    Write XLSX rows from an iterable of rows.
    Each row must be an iterable of writeable values.

    Returns the number of rows written
    """
    workbook = xlsxwriter.Workbook(filename)
    worksheet = workbook.add_worksheet()
    # Write values
    nrows = 0
    for i, row in enumerate(rows):
        for j, val in enumerate(row):
            worksheet.write(i, j, val)
        nrows += 1
    # Cleanup
    workbook.close()
    return nrows


def namedtuples_to_xlsx(filename, values):
    """
    Convert a list or generator of namedtuples to an XLSX file.
    Returns the number of rows written.
    """
    try:
        # Ensure its a generator (next() not allowed on lists)
        values = (v for v in values)
        # Use first row to generate header
        peek = next(values)
        header = list(peek.__class__._fields)
        return xlsx_write_rows(filename, itertools.chain([header], [peek], values))
    except StopIteration:  # Empty generator
        # Write empty xlsx
        return xlsx_write_rows(filename, [])

Example Usage:

MyType = namedtuple("MyType", ["ID", "Name", "Value"])
namedtuples_to_xlsx("test.xlsx", [
    MyType(1, "a", "b"),
    MyType(2, "c", "d"),
    MyType(3, "e", "f"),
])

This example will generate this table:

ID	Name	Value
1	a	b
2	c	d
3	e	f

 

How to fix GCC error: invalid use of incomplete type ‘class …’

Problem:

You are compiling a C/C++ program using GCC. You get an error message similar to this:

error: invalid use of incomplete type ‘class SomeType’

Solution:

There are multiple possible issues, but in general this error means that GCC can’t find the full declaration of the given class or struct.

The most common issue is that you are missing an #include clause. Find out in which header file the declaration resides, i.e. if the error message mentions class Map, look for something like

class Map {
   // ...
};

Usually the classes reside in header files that are similar to their name, e.g. MyClass might reside in a header file that is called MyClass.h, MyClass.hpp or MyClass.hxx, so be sure to look for those files first. Note that you might also be looking for a type from a library. Often the best approach is to google C++ <insert the missing type here> to find out where it might be located.

Another possible reason is that you have your #include clause after the line where the error occurs. If this is the case, ensure that all required types are included before they are used.

For other reasons, see StackOverflow, e.g. this post

Downloading & reading a ZIP file in memory using Python

Problem:

You want to retrieve a ZIP file by downloading it from an URL in Python, but you don’t want to store it in a temporary file and extract it later but instead directly extract its contents in memory.

Solution:

In Python3 can use io.BytesIO together with zipfile (both are present in the standard library) to read it in memory.
The following example function provides a ready-to-use generator based approach on iterating over the files in the ZIP:

import requests
import io
import zipfile

def download_extract_zip(url):
    """
    Download a ZIP file and extract its contents in memory
    yields (filename, file-like object) pairs
    """
    response = requests.get(url)
    with zipfile.ZipFile(io.BytesIO(response.content)) as thezip:
        for zipinfo in thezip.infolist():
            with thezip.open(zipinfo) as thefile:
                yield zipinfo.filename, thefile

 

How to store git HTTPS passwords / credentials permanently so you only have to enter them once

Problem:

Every time you clone a git repository or push/pull, you have to enter a username and a password (e.g. for GitHub or your GitLab installation).
Instead, you want git to store the password so you only have to enter it once.

Solution:

Configure the git credential helper to use a plaintext store instead of the default cache:

git config --global credential.helper store

NOTE: This approach will store your passwords in a plaintext file, so depending on your setup this might be a security risk.