Recent Work from the Week of May 11

More random work. Much of this week was

Protein Viewer for WordPress

It has been interesting to look back over how this has evolved and the span of technologies involved. I’m still looking at the sheer number of options for molecule viewing. The plugin is on github but is still a first-draft. It does use the free version of ACF and it is included in the plugin automatically.

And then I expanded to take URLs in addition to file uploads. There’s some weird stuff with mime types going on that I don’t quite understand. I can download a PDB file from the Protein Data Bank site but can’t upload it to WordPress. If I open the PDB file in Blender and export it as a PDB file it works fine. Checking on the mime type via terminal (file –mime-type -b yourFileName) seems to indicate they’re both the same. There are some slight differences in the text file itself but I don’t know what the problem is. In any case, the URL option gets around that problem and save storage space.

I revisit Tweets and keep adding over time. This is not sensible behavior.


I added the Zoom for GSuite extension and life with Zoom in GMail world is far more pleasant.

Gmail Syntax Highlighting lets me put code in gmail messages in ways that stay formatted. I do this enough to want this to work but hadn’t really thought about looking for a solution until Jeff posted something on code syntax highlighting in Google Docs in our Slack.

Slack Basics

I’m trying to setup a decent intro document for using Slack for our group.

A Google Sheets/Script Machine

I’m about 85% done with a spreadsheet/script/form combination that will let someone with no Google Scripting skills recreate a particular form pattern that creates a folder, shares some files, copies some other files etc. You can see the scripting for that below.

function onOpen() {
  var ui = SpreadsheetApp.getUi();
  // Or DocumentApp or FormApp.
  ui.createMenu('Machine Maker ?')
      .addItem('Create Maker Sheet', 'makeMachineSheet')      

function makeMachineSheet() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var machineSheet = ss.insertSheet('Machine Maker');
  machineSheet.getRange('A1').setValue('What is the ID of the folder that will hold all applications? ?').setBackground("#efefef")
  machineSheet.getRange('A2').setValue('What is the ID of the folder you want to give view access to? ?').setBackground("#efefef")
  machineSheet.getRange('A3').setValue('List the files (use the file ID) to copy to the lastname, firstname_topfoldername folder. ?').setBackground("#efefef")
  machineSheet.setColumnWidth(1, 450);
  machineSheet.setColumnWidth(2, 300);
//  var rights = SpreadsheetApp.newDataValidation().requireValueInList(['edit','view']);
//  machineSheet.getRange("B3:B20").setDataValidation(rights);

   SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
     .alert('Your machine maker details sheet is now ready.');

function FormSubmissionActions(){
  //get data from machine maker sheet
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var machineSheet = ss.getSheetByName('Machine Maker')
  var conentDestinationID = machineSheet.getRange("B1").getValue();//the folder ID where we save the new content
  var viewThisFolderID = machineSheet.getRange("B2").getValue();//the folder ID where we are giving view access 
   var formSheet = ss.getSheetByName('Form Responses 1');
   var rows = formSheet.getDataRange();
   var lastRow = rows.getLastRow();  
   var email = formSheet.getRange(lastRow,2).getValue();
   var firstName = formSheet.getRange(lastRow,3).getValue();
   var lastName = formSheet.getRange(lastRow,4).getValue();
   var atSymbol ='@');
   var cleanEmail = email.substring(0,atSymbol);
   addStudentToResourceFolder(cleanEmail, viewThisFolderID);
   makeStudentFolder(cleanEmail, lastName, firstName, formSheet, lastRow, conentDestinationID);


function addStudentToResourceFolder(emailClean, id){
  var folder = DriveApp.getFolderById(id);
  folder.addViewers([emailClean + '', emailClean + '']);//add student email versions as viewer

function makeStudentFolder(emailClean, lastName, firstName, sheet, lastRow, holderId){
  var draftId = createFolderBasic(holderId, lastName+ ', ' + firstName +'_Fulbright Folder');//create folder
  var draftFolder = DriveApp.getFolderById(draftId);//get folder
  draftFolder.addEditors([emailClean + '', emailClean + '']);//add student as editor
  var draftDoc = DriveApp.getFileById('1NqOqfEmNTLKbkl9yOpdaVuVuLXfMQPzbg7O62kRiTqo');//copy 
  draftDoc.makeCopy(lastName +', '+ firstName +'_Fulbright Drafts', draftFolder);  
  var url =  DriveApp.getFolderById(draftId).getUrl();

function createFolderBasic(folderID, folderName) {
  var folder = DriveApp.getFolderById(folderID);
  var newFolder = folder.createFolder(folderName);
  return newFolder.getId();

function makeLink(url){
   var sheet =  SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Form Responses 1');
   var rows = sheet.getDataRange();
   var lastRow = rows.getLastRow();
   var name = sheet.getRange('C'+lastRow).getValue();
   var formula = '=HYPERLINK("' + url + '","' + name +'")'

Me & My Presentation

This was inspired by a request from a faculty member teaching a speech class who wanted to see the presenter’s body language and the presentation at the same time. They found the Zoom presenter window to be too small. You can do some stuff with that on Zoom but not quite what I would want to do. You also might run into issues where you want to record your desktop on one of the free software options that doesn’t let you do picture-in-picture.

I thought I could make a nice, simple little page that would show a fairly large video window alongside a Google Presentation. That way your can record a single window and see it all at once or share that window on Zoom. It took about 20 or 30 minutes of work when I woke up way too early this morning but could become fancier with a little additional work.

You can check that out on CodePen here. You will need to approve the access to the camera to make it work.

Comments on this post

  1. carpetbomberz said on May 15, 2020 at 10:10 pm

    When I used to sysadmin an standalone apache server back in the day, I know that we occasionally had professors complain when they would sftp a file up to their website for students to click and download, the MIME type wouldn’t be defined and it would default to text-html, or whatever was set as a “fall-back” option in Apache. So I would go to some lengths to find that software manufacturers website (say Matlab) and see if they defined a MIME-type that would launch their app, as soon as the download completed, etc. Usually I could find a reference that they provided. But the fallback for me, was Object-Binary, especially for oddball calculation packages, with oddball file extensions. So I just attempted to lookup .pdb and got a hit on a website (don’t know how authoritative it might be)

    Suffix Media type/Sub-type
    .pdb chemical/x-pdb

    It was on this website:

    • Tom Woodward said on May 16, 2020 at 6:29 pm

      I appreciate you going to that effort. What’s frustrating me is I went through that and tried about 5 different combos including the chemical/x-pdb before I got this to work previously with the plain text version. I thought I had a way to identify mime types using terminal and then found that despite the terminal saying both files were the same text mime type, the one from the PDB site failed to upload to WordPress while the Blender export worked fine. I imported the file into Blender and exported it back out as PDB and it worked fine for WP at that point. I’ve been looking around at the internal file structure a bit but not seeing any rationale there. I think my next attempt will be to add multiple mime type combos for the PDB extension in WP and then see what happens. Maybe it all breaks. I feel like this stuff ought to be pretty straightforward but clearly isn’t.

      • carpetbomberz said on May 17, 2020 at 8:43 am

        Sounds like you went the full regression path. I remember too doing more than one entry for MIME-types on Apache, it’s worth a shot. I think if it gets a match on ANY of them, it will successfully load the file. But it is weird the file contents are the same but one works and the other one doesn’t.

Leave a Reply

Trackbacks and Pingbacks on this post

No trackbacks.

TrackBack URL