A cluster of mushrooms growing in pine needles
Microsoft Whiteboard Sticky Notes and Text Box
Two ways to add text to Microsoft Whiteboard sessions — ways that aren’t dragging your finger or mouse around in an attempt to draw legible text — are available. I’d like to be able to change the font in the text box — I get that their font choice is meant to evoke hand-written text, but it strikes me as non-professional.
PrivateTmp Strangeness — apachectl v/s systemctl
This is a very strange problem — we had a web server upgraded recently. We use “sudo apachectl start” to bring up the server since the server is maintained by a dedicated Unix support team, and the site worked fine. Until … Sunday morning after the log rotation. Then Box Spout was unable to access the XML data for an Excel file to compress it. Lots of errors:
[Mon Sep 14 10:59:39.137728 2020] [:error] [pid 57117] [client 10.1.2.3:49276] PHP Warning: ZipArchive::close(): Zlib error: stream error in /path/to/site/classes/vendor/box/spout/src/Spout/Writer/Common/Helper/ZipHelper.php on line 199, referer: https://hostname.example.com/path/to/code.php
[Mon Sep 14 10:59:39.137785 2020] [:error] [pid 57117] [client 10.1.2.3:49276] PHP Warning: fopen(/tmp/xlsx5f5f934699dcd9.17695276.zip): failed to open stream: No such file or directory in /path/to/site/classes/vendor/box/spout/src/Spout/Writer/Common/Helper/ZipHelper.php on line 213, referer: https://hostname.example.com/path/to/code.php
[Mon Sep 14 10:59:39.137803 2020] [:error] [pid 57117] [client 10.1.2.3:49276] PHP Warning: stream_copy_to_stream() expects parameter 1 to be resource, boolean given in /path/to/site/classes/vendor/box/spout/src/Spout/Writer/Common/Helper/ZipHelper.php on line 214, referer: https://hostname.example.com/path/to/code.php
[Mon Sep 14 10:59:39.137814 2020] [:error] [pid 57117] [client 10.1.2.3:49276] PHP Warning: fclose() expects parameter 1 to be resource, boolean given in /path/to/site/classes/vendor/box/spout/src/Spout/Writer/Common/Helper/ZipHelper.php on line 215, referer: https://hostname.example.com/path/to/code.php
[Mon Sep 14 10:59:39.138360 2020] [:error] [pid 57117] [client 10.1.2.3:49276] PHP Fatal error: Uncaught exception ‘Box\\Spout\\Common\\Exception\\IOException’ with message ‘Cannot perform I/O operation outside of the base folder: /tmp’ in /path/to/site/classes/vendor/box/spout/src/Spout/Common/Helper/FileSystemHelper.php:130\nStack trace:\n#0 /path/to/site/classes/vendor/box/spout/src/Spout/Common/Helper/FileSystemHelper.php(82): Box\\Spout\\Common\\Helper\\FileSystemHelper->throwIfOperationNotInBaseFolder(‘/tmp/xlsx5f5f93…’)\n#1 /path/to/site/classes/vendor/box/spout/src/Spout/Writer/XLSX/Helper/FileSystemHelper.php(369): Box\\Spout\\Common\\Helper\\FileSystemHelper->deleteFile(‘/tmp/xlsx5f5f93…’)\n#2 /path/to/site/classes/vendor/box/spout/src/Spout/Writer/XLSX/Internal/Workbook.php(134): Box\\Spout\\Writer\\XLSX\\Helper\\FileSystemHelper->zipRootFolderAndCopyToStream(Resource id #26)\n#3 /path/to/site/ in /path/to/site/classes/vendor/box/spout/src/Spout/Common/Helper/FileSystemHelper.php on line 130, referer: https://hostname.example.com/path/to/code.php
[Mon Sep 14 10:59:39.139468 2020] [:error] [pid 57117] [client 10.1.2.3:49276] PHP Warning: ZipArchive::close(): Zlib error: stream error in /path/to/site/classes/vendor/box/spout/src/Spout/Writer/Common/Helper/ZipHelper.php on line 199, referer: https://hostname.example.com/path/to/code.php
[Mon Sep 14 10:59:39.139504 2020] [:error] [pid 57117] [client 10.1.2.3:49276] PHP Warning: fopen(/tmp/xlsx5f5f934699dcd9.17695276.zip): failed to open stream: No such file or directory in /path/to/site/classes/vendor/box/spout/src/Spout/Writer/Common/Helper/ZipHelper.php on line 213, referer: https://hostname.example.com/path/to/code.php
[Mon Sep 14 10:59:39.139515 2020] [:error] [pid 57117] [client 10.1.2.3:49276] PHP Warning: stream_copy_to_stream() expects parameter 1 to be resource, boolean given in /path/to/site/classes/vendor/box/spout/src/Spout/Writer/Common/Helper/ZipHelper.php on line 214, referer: https://hostname.example.com/path/to/code.php
[Mon Sep 14 10:59:39.139533 2020] [:error] [pid 57117] [client 10.1.2.3:49276] PHP Warning: fclose() expects parameter 1 to be resource, boolean given in /path/to/site/classes/vendor/box/spout/src/Spout/Writer/Common/Helper/ZipHelper.php on line 215, referer: https://hostname.example.com/path/to/code.php
[Mon Sep 14 10:59:39.139599 2020] [:error] [pid 57117] [client 10.1.2.3:49276] PHP Fatal error: Uncaught exception ‘Box\\Spout\\Common\\Exception\\IOException’ with message ‘Cannot perform I/O operation outside of the base folder: /tmp’ in /path/to/site/classes/vendor/box/spout/src/Spout/Common/Helper/FileSystemHelper.php:130\nStack trace:\n#0 /path/to/site/classes/vendor/box/spout/src/Spout/Common/Helper/FileSystemHelper.php(82): Box\\Spout\\Common\\Helper\\FileSystemHelper->throwIfOperationNotInBaseFolder(‘/tmp/xlsx5f5f93…’)\n#1 /path/to/site/classes/vendor/box/spout/src/Spout/Writer/XLSX/Helper/FileSystemHelper.php(369): Box\\Spout\\Common\\Helper\\FileSystemHelper->deleteFile(‘/tmp/xlsx5f5f93…’)\n#2 /path/to/site/classes/vendor/box/spout/src/Spout/Writer/XLSX/Internal/Workbook.php(134): Box\\Spout\\Writer\\XLSX\\Helper\\FileSystemHelper->zipRootFolderAndCopyToStream(Resource id #26)\n#3 /path/to/site in /path/to/site/classes/vendor/box/spout/src/Spout/Common/Helper/FileSystemHelper.php on line 130, referer: https://hostname.example.com/path/to/code.php
The postupdate script is “systemctl reload httpd.service” — so not exactly the same thing we used to launch the service originally. But I’ve never seen differing behavior between apachectl and systemctl started HTTPD instances. Quick/dirty solution is to disable PrivateTmp, but I’m hoping to be able to isolate why exactly the postupdate script appears to break the service’s access to the private tmp space.
30 November 2020 addendum — In discussing the issue with RedHat, they suggested using either
/sbin/killall -HUP httpd
or
/bin/systemctl restart httpd.service > /dev/null 2>/dev/null || true
Doing this has allowed continual access to the Private Tmp space after log rotation. Woohoo! Not sure why the default configuration that came from the Apache httpd package didn’t work (i.e. it’s not like we built some funky weird log rotation script). But success is good enough for me.
Python Time-Expiring Cache
I needed to post information into a SharePoint Online list. There’s an auth header required to post data, but the authentication expires every couple of minutes. Obviously, I could just get a new auth string each time … but that’s terribly inefficient. I could also use what I had and refresh it when it fails … inelegant but effective. I wanted, instead, to have a value cached for a duration slightly less than the server-side expiry on the auth string. This decorator allows me to use the cached auth header string for some period of time and actually run the function that grabs the auth header string before the string is invalidated.
import functools
import time
from datetime import datetime
def timed_cache(iMaxAge, iMaxSize=128, boolTyped=False):
#######################################
# LRU cache decorator with expiry time
#
# Args:
# iMaxAge: Seconds to live for cached results.
# iMaxSize: Maximum cache size (see functools.lru_cache).
# boolTyped: Cache on distinct input types (see functools.lru_cache).
#######################################
def _decorator(fn):
@functools.lru_cache(maxsize=iMaxSize, typed=boolTyped)
def _new(*args, __time_salt, **kwargs):
return fn(*args, **kwargs)
@functools.wraps(fn)
def _wrapped(*args, **kwargs):
return _new(*args, **kwargs, __time_salt=int(time.time() / iMaxAge))
return _wrapped
return _decorator
# Usage example -- 23 second cache expiry
@timed_cache(23)
def slow_function(iSleepTime: int):
datetimeStart = datetime.now()
time.sleep(iSleepTime)
return f"test started at {datetimeStart} and ended at at {datetime.now()}"
print(f"Start at {datetime.now()}")
for i in range(1, 50):
print(slow_function(5))
if i % 5 is 0:
print(f"sleeping 5 at {datetime.now()}")
time.sleep(5)
print(f"done sleeping at {datetime.now()}\n\n")
print(f"Ended at at {datetime.now()}")
Ohio Absentee Ballot — Confirming Rejected Ballot
I requested an absentee ballot this year — we’d used absentee ballots once back when we lived in Geauga county and delivered the ballots to the Board of Elections office, but we generally vote in person. I wanted Anya to experience the process (and they give out cute stickers!). But we’ll have more time to explore what the ballot actually is at home, and there won’t be a bunch of people about. But — and the one thing that makes me want to do the early in-person voting — they can reject your ballot if the signature doesn’t match. I didn’t have a problem with my absentee ballot request, but Scott’s got rejected for a signature mismatch. And that had be worried about my actual ballot.
But, amid all of Trump’s blathering last night? Biden managed to convey that a lot of states have a process for curing rejected absentee ballots. I had no idea. Per Ohio Rev Code § 3509.06:
“(b) If the election officials find that the identification envelope statement of voter is incomplete or that the information contained in that statement does not conform to the information contained in the statewide voter registration database concerning the voter, the election officials shall mail a written notice to the voter, informing the voter of the nature of the defect. The notice shall inform the voter that in order for the voter’s ballot to be counted, the voter must provide the necessary information to the board of elections in writing and on a form prescribed by the secretary of state not later than the seventh day after the day of the election. The voter may deliver the form to the office of the board in person or by mail. If the voter provides the necessary information to the board of elections not later than the seventh day after the day of the election and the ballot is not successfully challenged on another basis, the voter’s ballot shall be processed and counted in accordance with this section.”
Which means I’d be notified if my ballot is rejected, and I could go to the Board of Elections within seven days of the election to provide whatever sort of identification they need to be satisfied. A total of fifteen states provide a remediation path for signature challenges — details for those states at https://www.ncsl.org/research/elections-and-campaigns/vopp-table-15-states-that-permit-voters-to-correct-signature-discrepancies.aspx
VSCode — Shortcut for Uppercase and Lowercase Conversion
While you can run a command to convert the selected text to upper (or lower) case, there doesn’t appear to be a quick way to do it. Luckily, you can define your own keyboard shortcuts and map those shortcuts to commands. From the File menu, select “Preferences” and “Keyboard Shortcuts” (or use the Ctrl-K Ctrl-S combo).
In the upper right-hand corner, click this icon to open the custom keyboard shortcut JSON file
Add JSON elements for the shortcuts you want to define — the key combination, the command to run, and on what to run the command
Sample key command bindings:
[
{
"key": "ctrl+shift+u",
"command": "editor.action.transformToUppercase",
"when": "editorTextFocus"
},
{
"key": "ctrl+shift+l",
"command": "editor.action.transformToLowercase",
"when": "editorTextFocus"
}
]
Save … voila, a keyboard shortcut to change to upper and lower case.
2020 Presidential Debate Number One
Large Numbers
It’s often difficult to conceptualize large numbers — something that allows statistics dealing with large numbers to convey something other than reality. I think I heard Trump say the government is ready to vaccinate 200k people a day. That sounds like a lot of people (it is a lot of people), but there are a lot of people in the US: an estimated 328.2 million according to a quick Google search.
That’s four and a half years to vaccinate the current population of the US at 200k a day, every day. Which doesn’t take into account new people being born (or aging into the range where a vaccine is administered). The CDC shows 3.79 million births in 2018 — of course that number changes every year, and it’s been decreasing. But at 3.5 million births per year, new people still add a few months to the vaccination timeline. About four and three quarter years to vaccinate the US population. And that assumes a one-dose vaccine. Administering two doses to everyone, at 200k people per year, would take just under ten years. Saying ‘it could take us five years to vaccinate everyone’ isn’t nearly as impressive sounding as ‘we can administer 200,000 vaccines each day’ — but it’s the same thing.
Speculation — Why he didn’t release his taxes
I’ve long speculated that Trump doesn’t release his taxes because beyond paying zero dollars (which everyone pretty much expects), he’s taking refundable deductions and having the government pay him. Well, the NYTimes has finally gotten access to years of returns for Trump and his businesses … and I’ve got a new hypothesis. It was only time before someone with access to Trump’s taxes sent that info to reporters. Had he stayed a private citizen, no one would have cared. And people who could have accessed the documents wouldn’t have bothered — they weren’t important.
The “loss” he claimed and carried back to request a 70 million dollar refund is questionable. If he got interest in the reformed company, he didn’t actually walk away from the investment. Before the tax returns were publicized, no one knew that the details of the subsequent transactions were of interest. Now that it’s public? Someone has access to information that’s pertinent to the IRS investigation. It’s only a matter of time before those details are splashed across some news paper’s page.
iJEMS Primer
The online docket site is located at http://www.co.medina.oh.us/medct_epublicnodr/UserLogin.aspx
Select “Public User Click Here” to enter the site.

Read the disclaimer; and, if you agree to the conditions, click “Accept”

Enter some search criteria – you can use a wildcard search (e.g. I wanted to find all of the Board of Zoning Appeals cases) or an exact name. By default, the date range is what I assume is their first record through today. Adjust as needed. Click “Search” to proceed.

You’ll get a list of matching cases. Click on one of the case numbers to view the case details.

You’ll see a case summary at the top of the window that appears. This will tell you the official case name, when it was filed, and the status. This is followed by a list of all of the parties involved.

Scroll down in that window to the “Actions” section, and you will see the case documents. Some will say “No Document” – for example, the case being filed is a record in the docket, but there’s no document. It’s just an event. Most items, however, will have a hyperlink that says “View” that can be used to open a PDF copy of the document.






