Project Insomnia

Project Insomnia is many things, but in this context it is simply a "braindump" of whatever I happen to be thinking/reading/watching/doing at the moment. Parental guidance suggested.

Tuesday, February 02, 2010

Block comments on SFGate.com

The "comments" section under every SFGate.com article is a cesspool (I'm not the first person to say this but I can't immediately find where it was said first) filled with hate, bigotry, trolling and various evil. Sure, you don't -have- to click through to the comments but SFGate helpfully shows the three highest-rated comments below each article--and the worst, and most prolific, commenters have hacking scripts that artificially inflate their comments' ratings. Here's another view on SFGate's comment section: link.

Feeling that "out of sight, out of mind" is a good policy, my first UserScript hides several DIVs associated with comments on SFGate article pages. Here's the source:


// ==UserScript==
// @name SFGate-NoComments
// @namespace http://www.userscripts.org
// @description Hide comments on SFGate.com articles
// @version 0.2
// @include http://www.sfgate.com/*
// @copyright 2010+, Andrew Rich (http://www.project-insomnia.com)
// @license (CC) Attribution Non-Commercial Share Alike; http://creativecommons.org/licenses/by-nc-sa/3.0/
// ==/UserScript==

var commentsDiv = document.getElementById('commentspage');
commentsDiv.style.display = 'none';
var commentslinksSpan = document.getElementById('commentslinks');
commentslinksSpan.style.display = 'none';
var commentBoxWrapperDiv = document.getElementById('articlePageCommentBoxWrapper');
commentBoxWrapperDiv.style.display = 'none';
var recCommentsDiv = document.getElementById('sfgate_recommended_comments');
recCommentsDiv.style.display = 'none';
var commentsListDiv = document.getElementById('commentslist');
commentsListDiv.style.display = 'none';
var commentsContainerDivAttrs = document.getElementById('Comments_Container_viewall').attributes;
commentsContainerDivAttrs.getNamedItem('class').value = '';
var commentsContainerDiv = document.getElementById('Comments_Container_viewall');
commentsContainerDiv.style.visibility = 'hidden';


I hope this is useful to you and thank you for reading. You can install it easily from the UserScripts.org link above. Tested in Safari 4.0.4 (5531.21.10) with GreaseKit 1.7 on Mac OS X 10.5.8 Build 9L30. Should work in other UserScript-supporting browsers (Firefox, Opera, Chrome "Dev Channel") without issue.

Labels: , , , ,

|| Andrew, 7:38 PM || || link ||

Saturday, January 23, 2010

Windows shell extension to easily add any folder to the PATH

How many times has this happened to you? You've downloaded a new Windows command-line tool and want to be able to use it from wherever your current directory happens to be, but the only way to add a folder to Windows' system PATH is via an unwieldy and hard-to-find modal dialog in the System Properties' Advanced tab. Well, I had just this problem last week when I was configuring some new machines and wanted to add some of my favorite command-line tools (mostly ports of Linux/Unix tools like which and less). I was about to go through System Properties to add their directory but figured there had to be a better way.

After a few minutes of Googling, I found this post by "/\/\o\/\/" which demonstrated a way of using Windows PowerShell (the next generation advanced command-line environment for Windows) to add a shell extension, used by right-clicking on any Explorer folder, which adds the selected folder to the system PATH.

Unfortunately, the code shown in the post didn't quite work as-is and besides I'm not too comfortable yet in PowerShell. So I decided to fix the code and build a script that does the same thing but from CMD (or by double-clicking). It's very simple to use; just execute the script from a CMD session or double-click it in Explorer. To uninstall, just run it again; it automatically backs out its changes when run a second time.

License and acknowledgement: The original (though non-working) code sample is by "/\/\o\/\/" and linked above; I claim no credit for it. However, I made it work and packaged it into a user-friendly script and so claim copyright over that portion under the GPL.

With that out of the way, here's the code:


::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: AddToPath.cmd ::
:: Written by Andrew Rich (andrew.rich@project-insomnia.com) ::
:: Copyright (c) Andrew Rich under GPL (http://gnu.org/licenses/gpl.html) ::
:: Based on code by "/\/\o\/\/" at http://bit.ly/58hYYh ::
:: ::
:: This command script adds an Explorer shell extension which, when ::
:: selected on right-clicking a folder, will add it to the system PATH. The ::
:: change takes effect immediately for new CMD or PowerShell instances ::
:: started after adding the folder to the PATH. CMD or PowerShell instances ::
:: started adding the folder will continue to use the PATH in effect at the ::
:: time they were started. ::
:: ::
:: Usage: ::
:: Double-click AddToPath.cmd or execute AddToPath.cmd from a CMD session. ::
:: The only command-line parameter available is /? which shows this text. ::
:: ::
:: Requirements: ::
:: - Windows XP SP3 or later. Not tested on Vista or Windows 7 BUT should ::
:: work unaltered. Please send feedback if you run AddToPath on Vista or ::
:: Windows 7. ::
:: - The user executing the command script must be a local Administrator. ::
:: However, the PATH update will affect all users. ::
:: - reg.exe must be on the system PATH. This should be the case for any ::
:: properly functioning Windows machine. ::
:: - Microsoft PowerShell must be properly installed. This should be the ::
:: case for any Windows machine which is current on Windows updates. The ::
:: command script will verify that PowerShell is installed. If the script ::
:: reports that PowerShell is not installed, download and install it from ::
:: http://bit.ly/mYzg4. ::
:: ::
:: Uninstall/remove: ::
:: Just run AddToPath.cmd again. If the "Add To Path" shell extension ::
:: installed by AddToPath.cmd exists, running the command script a second ::
:: time will cause the shell extension to be removed. ::
:: ::
:: Manual uninstall: ::
:: From a CMD session, type: ::
:: ::
:: reg delete HKCR\Folder\Shell\Add_To_Path ::
:: ::
:: Note that uninstalling only removes the Explorer shell extension, and ::
:: does not affect any system PATH entries which may have been added. ::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::ENDHEADERCOMMENT

@Echo Off
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

:: setup
SET ShellExtKey=HKCR\Folder\Shell\Add_To_Path
SET ShellExtKeyText="Add to Path"
SET PSPathKey=HKLM\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell

:: check command params
IF [%1]==[] GOTO CmdParamsDone
IF /I %1 EQU --help GOTO ShowHelp
IF /I %1 EQU /? GOTO ShowHelp
IF /I %1 EQU -? GOTO ShowHelp
GOTO ErrBadParam

:ShowHelp
ECHO.
FOR /F "delims=" %%A IN (%~fs0) DO (
IF /I %%A EQU ::ENDHEADERCOMMENT GOTO :EOF
ECHO %%A
)
PAUSE
GOTO :EOF

:ErrBadParam
ECHO.
ECHO "%1" is not a recognized command-line parameter for %0.
ECHO Type %0 /? for help.
ECHO.
PAUSE
GOTO :EOF

:CmdParamsDone
:: check overall prerequisite: reg.exe must be on the system PATH
reg 2>>NUL 1>>&2
IF NOT [%ERRORLEVEL%]==[0] GOTO ErrNoRegExe

:: is the Add_To_Path shell extension already installed?
:: if the reg query fails (errorlevel=1) then it's not installed
reg query %ShellExtKey% 2>>NUL 1>>&2
IF [%ERRORLEVEL%]==[1] GOTO Install
GOTO UnInstall

:Install
:: check install prerequisite: PowerShell must be installed
:: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell should contain the full path to powershell.exe
:: e.g. C:\WINNT\system32\WindowsPowerShell\v1.0\powershell.exe
FOR /F "usebackq tokens=3" %%a IN (`reg query %PSPathKey% /v Path ^| FIND "powershell.exe"`) DO SET PSPATH=%%a
IF NOT DEFINED PSPATH GOTO :ErrNoPowerShell
IF [%PSPATH%] EQU [] GOTO :ErrNoPowerShell

:: build the shell extension's command line
:: does powershell.exe's full path include spaces? if so, add quotes
FOR /F "tokens=2" %%a IN ("%PSPATH%") DO SET s=%%a
IF DEFINED s (
SET AddToPathCmd="%PSPATH%"
) ELSE (
SET AddToPathCmd=%PSPATH%
)
SET AddToPathCmd=%AddToPathCmd% -NonInteractive -NoProfile -Command [system.environment]::setEnvironmentVariable('path',$env:path + ';%%1','machine')

:: create the shell extension's base key under Folder\Shell
reg add %ShellExtKey% /ve /d %ShellExtKeyText% /f 2>>NUL 1>>&2
IF NOT [%ERRORLEVEL%] EQU [0] GOTO ErrRegAdd1

:: add the command line
reg add %ShellExtKey%\Command /ve /d "%AddToPathCmd%" /f 2>>NUL 1>>&2
IF NOT [%ERRORLEVEL%] EQU [0] GOTO ErrRegAdd2

ECHO Installed. Right-click on a folder in Explorer to add it to the system PATH.
PAUSE
GOTO :EOF

:UnInstall
reg delete %ShellExtKey% /f 2>>NUL 1>>&2
IF NOT [%ERRORLEVEL%] EQU [0] GOTO ErrRegDel
ECHO UnInstalled.
PAUSE
GOTO :EOF

:ErrNoRegExe
ECHO Error: reg.exe was not found on the system PATH.
PAUSE
GOTO :EOF

:ErrNoPowerShell
ECHO Error: Windows PowerShell is not installed (or is not installed correctly).
ECHO Go to http://bit.ly/mYzg4 to download and install Windows PowerShell.
PAUSE
GOTO :EOF

:ErrRegAdd1
ECHO Error creating the shell extension's base key.
ECHO Run %0 again to back out any changes.
PAUSE
GOTO :EOF

:ErrRegAdd2
ECHO Error adding the shell extension's command line.
ECHO Run %0 again to back out any changes.
PAUSE
GOTO :EOF

:ErrRegDel
ECHO Error removing the shell extension's registry entry.
ECHO To remove manually, type the following at the CMD prompt:
ECHO reg delete HKCR\Folder\Shell\Add_To_Path
PAUSE
GOTO :EOF



You can copy, paste and save that as AddToPath.cmd, or just download it (I recommend downloading it because line wrapping doesn't show properly here). AddToPath.cmd.zip

I hope this is useful. Please send me feedback if you use it!

Labels: , , , ,

|| Andrew, 1:21 PM || || link ||

Wednesday, March 05, 2008

Use a class to control whether links open in new windows (tabs) via JavaScript

This took me most of the day to figure out so I'm noting it here for anyone else who needs it. The object is to be able to set a list of links to open in a new window/tab without having to add target="_blank" to each and every one.

First, we wrap our list of links in a DIV and give it a class name to reference later:

<div class="extLinks">
<ul><li><a href="http://www.project-insomnia.com/">Project Insomnia</a></li>
<li><a href="http://www.mouseplanet.com/">MousePlanet</a></li></ul>
</div>


Of course that list of links could be much longer and adding the target="_blank" attribute to each one would surely be a pain. Having thus classed the list, here is the script to add to our HEAD section (or included script file):

function setExtLinkTargets()
{
for ( var e = 0; e < document.anchors.length; e++ ) {
if ( document.anchors[e].className == "extLinks" ) {
document.anchors[e].target = '_blank';
document.anchors[e].title = document.anchors[e].title + ' (opens in new window)';
}
}
document.divs = document.all ? document.all.tags('div') : document.getElementsByTagName('div');
for ( var f = 0; f < document.divs.length; f++ ) {
if ( document.divs[f].className == "extLinks" ) {
document.divExtLinks = document.all ? document.divs[f].all.tags('a') : document.divs[f].getElementsByTagName('a');
for ( var g = 0; g < document.divExtLinks.length; g++ ) {
document.divExtLinks[g].target = "_blank";
document.divExtLinks[g].title = document.divExtLinks[g].title + ' (opens in new window)';
}
}
}
}


This function has two parts; one that processes DIVs with class "extLinks" and another that processes individual links. Why the second? Because if we already have the overhead of the script running on the page load, we might as well have all of our new-window links controlled in one place. So we can also add class="extLinks" to any individual A element for the same effect.

Finally, we just need to call the script as soon as the page has finished loading. I like to put a general onLoadHandler() function in each of my pages:

function onLoadHandler()
{
// other onLoad stuff
setExtLinkTargets();
}


and call it from the BODY element's onload event:

<body onload="onLoadHandler();">

That's it! Now any list or group of links wrapped in a DIV of class "extLinks", or any individual links of class "extLinks" will open in a new window or tab.

Labels: , , ,

|| Andrew, 5:53 PM || || link ||

"Project Insomnia" and "project-insomnia.com" ™ & SM; site contents © Andrew Rich except where noted.