Make Facebook pleasant again

I go to Facebook every few days, weeks or whatever. Kids’ pics. Volleyball happenings. Doings of people I’ve known over the years.

What’s happened to my follow-feed, though, is people I know to be fine people in real life appear in the feed as the girl on the left:

Tantrum Time

This is disheartening at best.

Politics is entertaining, but, golly, let’s not scream at our favorite character on TV when they do something dumb. Get a grip.

But, of course, the other guy will never get a grip.

So, for Firefox, there’s Grease Monkey and my quick and dirty Grease Monkey script, FaceBookFix.user.js, to the rescue.

This script simply takes Facebook posts off screen if they contain, in text form (sadly not in images), any of a list of words.

It’s not heavily tested, to say the least. Which is to say, I tried it a couple times.

I made it easy to add or delete banned words. Non-programmers can change the script if they can find it on their disk and save it as a text file from WordPad or a better text editor.

The results are nice. My feed is now pleasant. Again. “Never do yourself what a computer can do for you,” so the computer now lets me see the real news un-flooded by noise. (If this post makes it to Facebook, I can’t write “f*** news” or the script will make the post invisible to me!)

Oh. Here’s the whole script as of this moment:

// ==UserScript==
// @name        FaceBookFix
// @namespace   https://www.tranzoa.net/~alex
// @description Get rid of sad Facebook tantrums.    https://www.tranzoa.net/alex/public_stuff/FaceBookFix.user.js
// @include     https://www.facebook.com/
// @version     1
// @grant       none
// ==/UserScript==

/***

    FaceBook posts containing any of these listed strings are whacked.

    The strings are in in no particular order.

    Change as you see fit.

    Non-programmers, leave the last one as the last one.

    Non-programers, for syntax reasons, do not put any:
        single-quote         ( ' )
        pipe/vertical_stroke ( | )
        backslash            ( \ )
    characters in any of the strings.

***/
var find_these_strings  = [
    'killary',
    'drumpf',
    'obozo',
    'shillary',
    'repuglican',
    'democrap',
    'libtard',
    'faux news',
    'hilliary',         // I forget other Internet commenters' alternate spellings. More to come, for sure.
    'trump',
    'hillary',
    'clinton',
    'HRC',
    'DJT',
    'obama',
    'biden',
    'pence',
    'nixon',
    'watergate',
    'reagan',
    'steve bannon',
    'stevebannon',
    'bernie sanders',
    'berniesanders',
    'bernie',           // Sorry about this, Bernie-from-Dimas-days. Your brand has been trashed.
    'sanders',
    'george bush',      // 'bush' is just too generic
    'georgebush',
    ' g bush',
    ' gbush',
    ' gw bush',
    ' gwbush',
    ' h bush',
    ' hbush',
    ' hw bush',         // did I get these bushes right?
    ' hwbush',
    'kkk',              // why are Hollywood and the news guys obsessed with the KKK? No one in the real world cares about them.
    'mcconnell',        // maybe this should be only mitch McConnell
    'sean spicer',
    'seanspicer',
    'harry reid',
    'harryreid',
    'paul ryan',
    'paulryan',
    'muslim',
    'impeach',
    'senate',
    'house of rep',
    'parliment',
    'merkel',
    'abortion',
    'pro-life',
    'prolife',
    'pro-choice',
    'prochoice',
    'occupy democrats',
    'occupy wall',
    'fake news',
    'iran',
    'iraq',
    'isreal',
    'saudia arabia',
    'potus',
    'scotus',
    'executive order',
    'daily show',       // ? poeple seem to feel this show is really important when it discusses politics
    'fuck',             // the whole profanity list should be here.
    'shit',
    'Note: Leave this here at the end of the list.'
    ];
find_these_strings  = find_these_strings.join('|').toLowerCase().split('|');
find_these_strings.pop();       // get rid of the comment at the end


(function (){

function    fix_this_facebook_thing()
{
    var divs = document.getElementsByTagName("div");                            //  Find all DIV elements in the page
    // window.console.log("fixing " + Date.now() + " " + divs.length);
    for (var el_number in divs)                                                 //  Python is *so* superior to JavaScript
    {
        var el  = divs[el_number];
        if ((el.id != undefined) && el.id.startsWith('hyperfeed_story_id_'))    //  For each post in the feed
        {
            var htm = el.innerHTML.toLowerCase();                               //  Look for any of the strings without regard to case
            // window.console.log("scanning " + el.id + " " + htm.length);
            for (string_number in find_these_strings)
            {
                var fs  = find_these_strings[string_number];                    //      For each of the strings to find
                if  (htm.indexOf(fs) >= 0)                                      //          Is the string in the post in text form? (sadly missing them in images and videos)
                {
                    el.style.display    = 'none';                               //          Yes. Take the post off screen
                    // window.console.log("whacked: " + fs + " in " + el.id);
                    break;                                                      //          And don't keep looking in the this post for more matches.
                }
            }
        }
    }
}


var timeout_every_couple_seconds = window.setInterval(fix_this_facebook_thing, 2017);


}());


// eof

Taking the fun away to be a better person

Twenty some years ago my right hand became frozen around a mouse. It took the left hand to pry the mouse from my … hand.

Why?

Microsoft Minesweeper.

Too much Minesweeper.

So, on the principle of “Never do yourself what a machine can do for you.“, I wrote a program to play the game. On screen. Mouse clicks and all.

And after watching expert mode being solved in 7 seconds a few times under Win 3.1, Minesweeper became boring and I stopped playing it. (No. The program did not use the cheat mode. It played fair.)

Problem solved.

Fast forward some years.

I wrote a program to solve Spider.

It didn’t help. I’ve still spent too much time on that game. But the program did find only a couple of impossible-to-win games out of 32 thousand dealt. That was informative.

Fast forward some more years.

I wrote a Sudoku program to stop myself from playing that game, uncompelling and bite sized though the game was. It was a fun program and is handy to find impossible and incompletely initialized / ambiguous games (e.g. at sudoku.com). But it didn’t satisfy.

Fast forward to now.

And we have a screen shot from sudo_ku.py playing a game at www.WebSudoku.com :

Playing Sudoku the right way.

We’ll see if I keep playing this site’s game.

Or a hacked old Python Gnome Sudoku program:

Playing Gnome Sudoku the right way.

The program looks at the screen(s), finds boards, solves them, and plays them using mouse clicks and keys to enter the numbers. Though the program is incomplete, it’s pretty satisfying. Perhaps that’s why at one point many years ago I said that my job was to automate my job. And perhaps that’s why I’m not among the robotic hand-wringers of today. It’s simply fun to watch machines do what they do best.

Paper Tape

As can be clearly seen by the octal values, this is a scan of the mylar tape of the Super Wrinkle boot loader for the APS-73 Computer used in Autologic typesetters.

super_wrinkle_boot_loader_in_mylar_small_01

Super Wrinkle, if I recall, was the ultimate boot loader – a worthy successor to the famous Wrinkle loader. Super Wrinkle required the minimum possible switch toggling to be read from the tape reader. Once it overwrote the toggled instructions, it read a more complex, generic, non-hacky loader. This had to be done after any power cycle / reset / program failure / hardware glitch.

The alternative to toggling in the instructions to read an infinite number of (Super Wrinkle) bytes from the tape reader was too expensive for everyday computer use. We’re talking $27 for a mighty, 256 byte ROM chip. That was back when $27 was $27, mind you. One customer built such a device out of discrete diodes to save the cost. The word was it was quite a monstrosity.

Installing opencv 2.x on Ubuntu Lucid

Lucid include opencv version 1.x. That version doesn’t cut it.

Here is how to get the latest (as of March 15, 2014) opencv going under Lucid.


sudo aptitude install cmake libdc1394-utils libjasper-dev libavcodec-dev libavformat-dev libswscale-dev

#
# cd to some temporary directory, download the latest opencv ZIP file and then ...
#
unzip opencv-2.4.8.zip
cd opencv-2.4.8

#
# Get around that we need a newer cmake according to the Internet - commenting out the problem is the easy way to fix it
#
cp ./cmake/cl2cpp.cmake ./cmake/cl2cpp.cmake.original
perl -ne "~s/string\(MD5/# string\(MD5/; print" < ./cmake/cl2cpp.cmake.original >./cmake/cl2cpp.cmake

#
# -D MAKE_FFMPEG=OFF 'cause we need a newer ffmpeg - so opencv will just not be able to do things ffmpeg allows
#
mkdir -p release
cd release
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_FFMPEG=OFF ..

# make using as many CPUs as you have - 4 in this case
make -j4
sudo make install

# verify this version of opencv works with a usable language
python -c "import cv2; print cv2.__version__"
2.4.8

Python 3

Read an interesting screed on Python 3.

Thoughts on Python 3

Agreed.

This paragraph pretty much sums it up:

Python 3 is in the spot where it changed just too much that it broke all our code and not nearly enough that it would warrant upgrading immediately. And in my absolutely personal opinion Python 3.3/3.4 should be more like Python 3 and Python 2.8 should happen and be a bit more like Python 3. Because as it stands, Python 3 is the XHTML of the programming language world. It’s incompatible to what it tries to replace but does not offer much besides being more “correct”.

I really like Python. Moved from Perl (for PC work) when CPU’s got fast enough for Python. The Python out-of-box was terrific.

But, Python 3 is another language. I can’t justify porting all my personal “library” code to another language. Some of the Python 3 stuff reminds me of C++ – puffiness for the sake of puffiness. If forced to go to Python 3, I’d evaluate what language to use as I did when moving from Perl.

And as it stands, it’s very clear that, since all the garbage-collection-memory-protection languages are equivalent, the last one standing will be JavaScript. You have to write the occasional JavaScript. So you have to pay the entrance fee. Maybe node.js will end up making JavaScript work reasonably as a non-browser language. Something will. And that’s the end of all the other languages (excepting the type-anal ones for corporate cubicles). Poof. Python 3 becomes a non-issue.

If Python ran in the browsers and if it ran on all the newer OS’s, then fine. It could go head to head with JavaScript. Otherwise … Too bad. Sad. I may be a curly bracket guy, but Python just looks and feels better than JavaScript.

rsync and sshpass

After spending yet another several hours fighting the good fight, it seems like a good idea to note how to use rsync on a troublesome ssh connection – one that both requires a password and that is slooooow to get logged on.

First, the problem of the password is solved using sshpass. It allows you to put the password for the remote system in a file. The file, we presume, is stored in your ~/.ssh/ directory and has its permissions set so that only you, the user, can see it or do anything with it. In that way, it works like an ssh key file that you might tell ssh to log in with using the “ssh -i ...” command line option.

Second, to allow for a slow server, use something like this as an option to ssh:

ssh -o ServerAliveInterval=45 ...

That is, tell ssh to wait for 45 seconds for the slow server to get you logged in.

So the command line to get a connection to the server is something like this:

sshpass -f ~/.ssh/bonzo_password.txt       \
             ssh                           \
            -p __BONZO_SSH_PORT_22__       \
            -o ServerAliveInterval=45      \
             __BONZO_USER__@__BONZO__


Excuse the horrid backslashes. They are for the browser window.

All well and good. But that command line won’t work under rsync. The connection will be made, then instantly dropped. And rsync hangs.


I presume the drop is something security-related in ssh.
Or maybe sshpass.
Whatever.
rsync is unhappy.

But, here’s the deal: rsync will be happy if the connection is already made in another terminal, and you have configured ssh to allow connections to go through a “master” connection – that is, tell ssh to not log in normally, but to rather use an existing ssh connection.


You tell ssh to use an existing connection by putting the following in a ~/.ssh/config file (remember to set the permissions for everything in ~/.ssh for only your access):

ControlMaster       auto
ControlPath         /tmp/ssh_mux_%h_%p_%r

For clean-up reasons, you put the sshpass command in a separate .sh file which we’ll call ssh_to_bonzo.sh.

So now you run that ssh_to_bonzo.sh script in a “SCREEN” – sort of a virtual terminal window!

screen -t ssh_to_bonzo -dmS ssh_to_bonzo ssh_to_bonzo.sh
sleep 45


Note the you-set-it, 45 second delay.

Once this code is run, you can rsync away, though with the world’s worst command line.

So your whole rsync script might look something like this:

screen -t ssh_to_bonzo -dmS ssh_to_bonzo ssh_to_bonzo.sh
sleep 45
rsync --rsh="sshpass -f ~/.ssh/bonzo_password.txt ssh -l bonzo_user_name"     \
        bonzo:bonzo_directory                                                 \
        to_directory
pkill ssh_to_bonzo.sh

Or something of that sort.

Notice the pkill ssh_to_bonzo.sh at the end. That cleans up the screen operation.

Note, too, that you must still give the sshpass command line to the rsync --rsh option.

Piece of cake.

Pulsing Web Page

Years ago, I daydreamed about a head’s up display for futuristic Instant Messaging. The display would show vital signs of the “buddy” you were monitoring. Such an intimate thing might help with communication.

Seemed like a good idea at the time.

Well.

https://www.tranzoa.net/alex_pulse/

Viewing this waveform from the CMS50E requires an HTML5-capable browser (Firefox / Safari / Modern phones / Webit / maybe IE9). I do not know how timely the waveform will show up from outside the house. It updates on localhost about once a second – roughly in time with the heartbeat beeping from the device.

Alex Pulse

The waveform just stays put if the “finger” is out. Who knows what will happen when the device is not connected to the PC that runs the server.

The “finger” is my left index toe.

left toe

The project got a little out of hand. The general idea is to have a generic server that makes it easy to stream line/point numbers out to arbitrary numbers of web clients to graph. I cut things short to get this thing on line.

Internet oddity

Have you ever noticed that Google has skipped a UI beat in Google Maps and Google Earth?

Try entering a latitude / longitude value to either.

Unless you get it exactly right, both systems fuss and stonewall.

Why?

Is there some silly patent out there?

Anyway, it turns out that parsing lat/lon gets dirty fast. Sort of like parsing arbitrary time/dates.

Here’s a shot: /cgi-bin/latlon_cgi.py.

Har, har. Should someone write a GreaseMonkey script to “fix” input to Google Maps with an XMLHttpRequest? That would be keeping in the Web 2.0 river.

Changing a program you don’t know

How might a language help solve the problems of those who wish to safely add code to a big project that they don’t understand very well.

Well, such a language might make it hard to build a program with the “pragma assert”s stripped out. (Stripping asserts is a powerful tool for those who spend time “proving the correctness of programs” or who, in the dark recesses of their minds, agree with the thinking of the early days of computers: “A bug?!? Why, that’s so totally unexpected!”)

And, could you be encouraged to write self-test code that does not execute in-line, but rather works kind of like a conditional hardware breakpoint at a higher, more complex level?

Heck, there’s gotta be some way to keep all these multi-core CPUs busy.

Now, if you could build a system that wrote such high-level, self-test code – that would be kinda interesting.

The promise of open source

It’s funny how the promise of open source is an unreachable ideal.

Let’s take a popular open source project: Thunderbird.

Gosh, it would be nice to make a few changes to it.

But it’s too big. And, as a guess, you’d need to spend a lot of time (and perhaps money) setting up a development environment to actually work on it.

In an imaginary, ideal world, such a program would be made up of many clearly labeled, independent, smaller parts with clear, decoupling APIs between them.

Yes, there would always be a bucket of shared library, “memcpy” kinds of things. But those things should just be there in an opaque monolith, always available, never obtrusive.

And, in that ideal world, the pieces of the program would be written in a modern language (i.e. not C/C++).

Telling experience: A few years ago, I needed the Perl POP3 module to do something. Since the source was part of Perl, I simply modified it, sent the author/owner (whose contact information was at the top of the source file) the change and moved on. Soon thereafter, I noticed he had imported the change in a better, more general way. That was all good and pleasant. That the program ran directly from the source was the enabling factor there.

I wonder how much FireFox and Thunderbird would be improved if there were a Tools|Advanced button to toggle the UI/Javascript source between the .jar file format it’s in and a fully expanded form. … And much more of the program were moved up to Javascript from C++. … Or if writing extensions weren’t so chaotic a process.