tag:blogger.com,1999:blog-30624302024-03-06T19:50:39.512-08:00Vic’s BlogWork. Play. Think. Love. Life.Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.comBlogger95125tag:blogger.com,1999:blog-3062430.post-56106229188893189722021-04-08T01:59:00.004-07:002021-04-08T02:13:03.230-07:00Jira next-gen - Open task in a new tabOpening a Jira issue in a new tab takes a lot of clicks. I wrote a user-script to make it easier - alt-click an issue in a board or backlog view will open that issue in a new tab.<p></p>
<div style="clear: both;"></div><div><a href="https://openuserjs.org/scripts/vshih/Jira_next-gen_-_Alt%2Bclick_to_open_issues_in_new_tab">https://openuserjs.org/scripts/vshih/Jira_next-gen_-_Alt%2Bclick_to_open_issues_in_new_tab</a></div>Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com0tag:blogger.com,1999:blog-3062430.post-78012933527774426642020-05-23T00:21:00.000-07:002020-05-23T00:21:22.488-07:00Automatically Dismiss Google Docs' "You're currently signed in as ..." Pop-upTired of seeing these on Google Docs?<br />
<br />
<br />
<div style="clear: both;">
</div>
<img border="0" data-original-height="269" data-original-width="397" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKwrDRZqxA13iHZDsNDWH9Q_3rYBK8-CPJUsWQbvN7B_b6zY63brUa_xKLYaaqQnvo2xtFliyxw4YkHcvAINFhjhVC1YXmVgzRIfT9rQBUjNQhriGsxiA3ZYq8UnnSLmgJsnJADA/s1600/google-docs-signed-in-as.png" />
<br />
<div style="clear: both;">
</div>
<br />
<br />
I was. I wrote a <a href="https://www.tampermonkey.net/">Tampermonkey</a> script to dismiss it automatically:<br />
<br />
<a href="https://openuserjs.org/scripts/vshih/Google_Docs_-_dismiss_signed_in_as">https://openuserjs.org/scripts/vshih/Google_Docs_-_dismiss_signed_in_as</a><br />
<br />
Check it out. This issue was discussed on Google's <a href="https://support.google.com/docs/thread/10858404?hl=en">Docs Editors Help</a>, but the question has since been closed.<br />
<br />Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com2tag:blogger.com,1999:blog-3062430.post-54903124277532385482018-10-20T13:03:00.000-07:002020-05-23T00:22:01.370-07:00"Not My First Rodeo" (Me, About My Second Rodeo)Everyone said second labors are much faster than the first, but we really had no idea how true that was. Three pushes and Wesley was out! Six pounds, five ounces.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLi9992Wx-dZQlkOgZWgJN2oNuJa564bzAEhykIOzXg3WOa6YTI2UAV3FZ0MM8Wx0wClBzcG6hkSS3Agq7eNCFdPtC0bxbaWXopAjO4e_luX-rixr-RnL49cYysslJFscBceTwBQ/s1600/IMG_20181001_145000943.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1600" data-original-width="899" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLi9992Wx-dZQlkOgZWgJN2oNuJa564bzAEhykIOzXg3WOa6YTI2UAV3FZ0MM8Wx0wClBzcG6hkSS3Agq7eNCFdPtC0bxbaWXopAjO4e_luX-rixr-RnL49cYysslJFscBceTwBQ/s320/IMG_20181001_145000943.jpg" width="179" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOQVGsUAKgOJDiPky0ycF8-z49fKuorkbL0S-CR5JNrn3J7oXrsMLusvWp6HY-U0h2nn4X8DHUYq9yJmHfdNZb_-34wnpcTjKfI1NEk5ei4kubVx-dBE70qudy5yrnJnI8LbWjlw/s1600/IMG_20181001_162848179.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="720" data-original-width="1280" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOQVGsUAKgOJDiPky0ycF8-z49fKuorkbL0S-CR5JNrn3J7oXrsMLusvWp6HY-U0h2nn4X8DHUYq9yJmHfdNZb_-34wnpcTjKfI1NEk5ei4kubVx-dBE70qudy5yrnJnI8LbWjlw/s320/IMG_20181001_162848179.jpg" width="320" /></a></div>
<br />
Vicki did great, and is thrilled to be done with the dieting!<br />
<div style="clear: both;">
</div>
Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com0tag:blogger.com,1999:blog-3062430.post-35073755549825189932018-06-12T01:47:00.001-07:002020-05-23T00:21:42.683-07:00Imgur NumberingI made a thing! It's a Chrome extension that adds numbering to <a href="https://imgur.com/">Imgur</a> images.
<br />
<br />
Unless there's only one image, of course. That would be silly.
<br />
<br />
Get <a href="https://chrome.google.com/webstore/detail/imgur-numbering/ankgddgkcflpakdolgoijaimpoafpmie">Imgur Numbering</a> in the Chrome Web Store, and comment here if you have issues.
<br />
<br />
<div style="clear: both;">
</div>
Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com1tag:blogger.com,1999:blog-3062430.post-58888391107767561972014-06-08T21:26:00.001-07:002014-06-08T21:26:17.786-07:00The Big DayIt was certainly the most harrowing experience of my life. All the more terrifying considering we hope to go through it again at some point.<br />
<br />
We called the doctor's office around 5:30am; Vicki was in a bit of pain but her water had not broken and her contractions were not very consistent. The doctor on-call told us, in a way which clearly indicated he was not quite awake, to wait until the contractions became more consistent. We both tried to get some rest again. I was much more successful, unsurprisingly.<br />
<br />
At 9ish Vicki woke me up to tell me the contractions were becoming unbearable. We called the office again, and this time our doctor was on duty. He told us to come in.<br />
<br />
We got to the hospital around 9:30am. Turns out Vicki was at 8cm already. A bit flustered, I scrambled to tell her family and wondered if they would be able to get here in time.<br />
<br />
Vicki was fully dilated pretty soon, but we tried a few things to get the baby to turn around before trying to push. Eventually they had Vicki start pushing at 1pm. She started off making good progress, but after about two hours or so, things got stuck somewhat. The nurse started telling Vicki to rest every other contraction, and I was getting increasingly anxious watching the baby's heart-rate drop during every push. All the while the possibility of resorting to a C-section loomed, something none of us wanted.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_SzJRamZDzsXnZiTNULrK2sUX5AfIyLqaBW9LSkjpGRSoxFWmd68nUb2Vn81ato_9FoRWCynty7U_REzJGkMplO6kpvvtiPQosRhIaBVM91z-Malm-5NYrT92a7zbs_t6g9fQSw/s1600/2014-06-03+14.45.01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_SzJRamZDzsXnZiTNULrK2sUX5AfIyLqaBW9LSkjpGRSoxFWmd68nUb2Vn81ato_9FoRWCynty7U_REzJGkMplO6kpvvtiPQosRhIaBVM91z-Malm-5NYrT92a7zbs_t6g9fQSw/s1600/2014-06-03+14.45.01.jpg" height="320" width="179" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6QfLux_1a1_1tQ18yY80qf9bPrHccMzCNyQh_iV1rRIRPb2wDbmYb03EPwzW6LN7ZuDsDQzfq0Ao6bH4xv_BwgGlaq-oVUzq_kcvXO-8wbQh-qRCHWbWvghgfbeQwmH4J59FCJg/s1600/2014-06-05+12.09.59.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6QfLux_1a1_1tQ18yY80qf9bPrHccMzCNyQh_iV1rRIRPb2wDbmYb03EPwzW6LN7ZuDsDQzfq0Ao6bH4xv_BwgGlaq-oVUzq_kcvXO-8wbQh-qRCHWbWvghgfbeQwmH4J59FCJg/s1600/2014-06-05+12.09.59.jpg" height="320" width="179" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzPbmpDb93e6yqJC-f3r-gDFXyxgoc_0SSTwTUtWY0ZjLdFf0KublsO9kelXuqEKcPkJIjAU6wi1kwici8jndU6i0ZVLmObu9eiooHDKy1IohB7S8YKwNxAGr8xxXCYq-bBi83jw/s1600/2014-06-05+19.34.24.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzPbmpDb93e6yqJC-f3r-gDFXyxgoc_0SSTwTUtWY0ZjLdFf0KublsO9kelXuqEKcPkJIjAU6wi1kwici8jndU6i0ZVLmObu9eiooHDKy1IohB7S8YKwNxAGr8xxXCYq-bBi83jw/s1600/2014-06-05+19.34.24.jpg" height="320" width="179" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
At the three-hour mark we decided to try suction. The room bustled as preparations were made; scrubs were donned, and the doctor put Vicki into stirrups which were of course too big for her. The plastic suction grip was attached, some violent maneuvers ensued, and baby Warren was out, a full mane of hair adorning his impressive torpedo of a head. Born face-up with the cord around his neck, he looked exhausted; his cries were so feeble as the pediatrician whisked him to the warming bed. I cried too, watching him there, both of us so helpless.</div>
<br />
The first week had its share of anxieties too. Warren wasn't sleeping well the first few nights, and I was afraid I might go crazy, anticipating the next three weeks of the same. Turns out Vicki's milk took a while to come in, and the little guy managed to drop to 5.1 lbs by that Friday. We started him on formula at that point, which eased his fussiness a lot at night and he soon returned to his birth weight. Tomorrow we find out the progress he has made since then.<br />
<br />
Life, as Vicki and I have known it up to this point, appears to have been changed forever...<br />
<br />
<div style="clear: both;">
</div>
Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com1tag:blogger.com,1999:blog-3062430.post-46178781065105522802014-05-26T22:43:00.003-07:002014-05-27T00:17:33.766-07:00Warren Tran ShihBorn May 26, 2014, 3:57pm<br><div>5 pounds, 11 ounces; 19 inches<br>
<br>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDdyUtEsfqSjGg0MadiDnZQWnafpl8SNN7E5f0c1iFJzSfy0omRZFk94m315LtoWgX8b-i6jDI2Yt0rf2srYRGxTxF7oPo1fWSnSI_GDdob331j-F_t_WwPT93oeEaqTyc9eXg6g/s1600/IMG_20140526_160718941.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDdyUtEsfqSjGg0MadiDnZQWnafpl8SNN7E5f0c1iFJzSfy0omRZFk94m315LtoWgX8b-i6jDI2Yt0rf2srYRGxTxF7oPo1fWSnSI_GDdob331j-F_t_WwPT93oeEaqTyc9eXg6g/s1600/IMG_20140526_160718941.jpg" height="179" width="320"></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQkC-tB_g8x2PeypMp0tlvVJLJe-oroeqKIV5j1t-DnKVXEP0UO7DpoN3pULtXrNwXme4hmRxAJIBmDYTLrEzYB29ILJZyioRYzSpRgKy4g1NA5Uwh6P1K-cVNO8M5NE-f2ZDUZw/s1600/IMG_20140526_183352132.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQkC-tB_g8x2PeypMp0tlvVJLJe-oroeqKIV5j1t-DnKVXEP0UO7DpoN3pULtXrNwXme4hmRxAJIBmDYTLrEzYB29ILJZyioRYzSpRgKy4g1NA5Uwh6P1K-cVNO8M5NE-f2ZDUZw/s1600/IMG_20140526_183352132.jpg" height="320" width="180"></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br></div>
<br></div>Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com11900 Sullivan Avenue, Daly City, CA 94015, USA37.6797615 -122.4745007999999937.655254 -122.51484129999999 37.704269 -122.43416029999999tag:blogger.com,1999:blog-3062430.post-72555852870388983832012-09-30T20:12:00.000-07:002012-09-30T20:43:46.039-07:00Daly Tripper<div style="float: left; margin-right: 10px;">
It's been a few weeks now in our new city! We took advantage of the weekend and made a trip to Golden Gate Park.<br />
<br />
While we waited for the Muni at the Daly City <span style="font-size: x-small;">BART</span>, an elderly Asian lady tried talking to us, but we couldn't understand her. Finally she pointed to something behind us. Turns out we were waiting at the wrong stop; she must have noticed we were waiting for the 28-bus after seeing us rush to catch the one that just left. I was impressed that she put in the effort to let us know!<br />
<br />
We ate and picked up some random necessities at different shops. We even dropped by an estate sale along the way. It turned out to be a really nice, sunny day, which was a huge contrast for me, being cooped up in gloomy, foggy Daly City all week. Here's a picture of us waiting for the bus again, enjoying our first (quite cheap) "self-serve boba" milk tea:</div>
<div style="clear: both;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLdDOsnO5KkyIoGNZqDai6mGu_6mgTeU-FDLNH4rFczHx5PB_Zl1wbWQcJLSOwDzVn_KrwTkZRkDny00Jrgc8O6ZMCVTA-XcrdniLBPXD5M5WmR76a5jMoPkx09cTiIdJi7xra9g/s1600/photo.JPG" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLdDOsnO5KkyIoGNZqDai6mGu_6mgTeU-FDLNH4rFczHx5PB_Zl1wbWQcJLSOwDzVn_KrwTkZRkDny00Jrgc8O6ZMCVTA-XcrdniLBPXD5M5WmR76a5jMoPkx09cTiIdJi7xra9g/s200/photo.JPG" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Public transportation gluttons</td></tr>
</tbody></table>
Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com0tag:blogger.com,1999:blog-3062430.post-80854632043731891192011-10-14T00:18:00.000-07:002011-10-14T00:54:18.512-07:00Hitched<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh57Nj-SD94VHhmAjEmUM3ODCFLOcVLD0D9RY3dENqQefE2uOGlRriDZJOW2M9c5X0rCoWTDgZULHyl7x7dwG9HnkDWr8QB3uAP2fNoamgVrD7ZBDk0kWcVvZSa7xU8bt_SlkE5mw/s1600/IMG_5548.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh57Nj-SD94VHhmAjEmUM3ODCFLOcVLD0D9RY3dENqQefE2uOGlRriDZJOW2M9c5X0rCoWTDgZULHyl7x7dwG9HnkDWr8QB3uAP2fNoamgVrD7ZBDk0kWcVvZSa7xU8bt_SlkE5mw/s640/IMG_5548.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">photo: Alan Harris</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Wow. It really happened! I put in my share of time and effort, but really Vicki gets all the credit. Somehow we managed to pull it off in these past three months.<br />
<br />
I'd like to give a very heartfelt thanks to everyone who went out of their way to attend. If it wasn't the most complicated ceremony/reception arrangement possible, it must have been close to it. It meant so much to us to be able to see all of your faces. Friends and family came from as far north as Seattle, as far south as Texas, as far west as Taiwan, and as far east as France. As much as Vicki and I dislike being the center of attention, we are so moved by the love and support you all have shown us.<br />
<br />
And as if coming out all that way wasn't enough, everyone gave us so much! Thank you all for your kind generosity.<br />
<br />
It would be impossible to adequately thank everyone who helped make this happen. We definitely could not have done it without the help of: Vicki's mom, aunts and uncles; her sisters Karen, Mimi, and Betty; and her bridesmaids Joanne and Ann. A special thanks to groomsmen Ben and Joel (and their wives, Claire and Joanne) for throwing me a blast of a party and as well as staying so on top of things throughout the entire marathon of a day.<br />
<br />
And a heartfelt apology to all those we couldn't invite. Hopefully we will get to see all of you in the near future.<br />
<br />
Thanks again, everyone!<br />
<br />
P.S. I also deeply apologize for the band at the reception. Yikes.Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com0Oxnard, CA, USA34.1975048 -119.177051634.0924383 -119.3349801 34.3025713 -119.0191231tag:blogger.com,1999:blog-3062430.post-54346193718731979812011-09-04T20:27:00.001-07:002021-06-29T21:56:23.767-07:00CloudDiff Chrome Extension<br />
<b></b><a href="https://chrome.google.com/webstore/detail/clouddiff/hlmlielnekakcdfpkbgcpnphenleogfp?hl=en-US&gl=US" target="_blank">CloudDiff</a> - Compare versions of your Dropbox or pCloud text files in-browser or using your configured diff tool.<br />
<br />
<h4>
Updates</h4>
<b></b><div><br /></div><b>2021-06-28 update (version 1.0.2.28)</b> - Handle Dropbox failure earlier. Button to clear Dropbox token.<br /><div><br /></div>
<br />
I've written <a href="https://chrome.google.com/webstore/detail/clouddiff/hlmlielnekakcdfpkbgcpnphenleogfp?hl=en-US&gl=US" target="_blank">CloudDiff</a>,
a Chrome extension which allows you to compare different versions of text files you have on <a href="https://www.dropbox.com/" target="_blank">Dropbox</a> or <a href="https://www.pcloud.com/" target="_blank">pCloud</a>. It can perform the diff in-browser, or trigger a diff tool you have installed on your local machine already, which you must configure.<br />
<ol>
<li>On the Dropbox website, browse to the "Version history" page of any text file.</li>
<li>On the pCloud website, browse to the "Revisions" page of any text file.</li>
<li>A "Diff" column has been added where you can select which two versions to compare.</li>
<li>To trigger your already-installed diff tool, click the "Diff" button.</li>
<ol>
<li>If a diff tool is not yet configured, the Options page opens where you can specify one. If you don't have one installed already, one option is <a href="http://kdiff3.sourceforge.net/" target="_blank">KDiff3</a>. The setting is accessible from Tools > Extensions > CloudDiff > Options.</li>
<li>An additional executable must be installed, <a href="https://bitbucket.org/vshih/clouddiff-helper/downloads" target="_blank">CloudDiff Helper</a>, in order to trigger your diff tool. Follow the <a href="https://bitbucket.org/vshih/clouddiff-helper" target="_blank">instructions</a> to install.</li>
<li>If configured correctly, your diff tool should open.</li>
<li>To perform the diff in-browser, click the "Inline" button.</li>
</ol>
</ol>
<div>
This should run on Windows, Mac, and Linux. Note that the combined file-size limit in any comparison is 4GB. Please let me know if any issues come up.</div>
<br />
<div style="clear: both;">
Get <a href="https://chrome.google.com/webstore/detail/clouddiff/hlmlielnekakcdfpkbgcpnphenleogfp?hl=en-US&gl=US" target="_blank">CloudDiff</a>.<br />
<br />
<h3>
</h3>
<h4>
Privacy Policy</h4>
<div>
<div>
<a href="https://github.com/vshih/CloudDiff/blob/master/privacy-policy.md">https://github.com/vshih/CloudDiff/blob/master/privacy-policy.md</a></div>
</div>
<div>
<br /></div>
<h4>
Release History</h4>
<span style="color: #999999;"><b></b></span><br />
<span style="color: #999999;"><b>2020-06-01 update (version 1.0.2.27)</b> - Upgrade to jQuery 3.5.1, CodeMirror 5.54.0. Handle OAuth token expiration. Fix pCloud caching behavior.<br style="color: black;" /></span></div><div style="clear: both;"><span style="color: #999999;"><span style="color: black;"><br /></span></span></div><div style="clear: both;"><span style="color: #999999;"><b>2020-05-08 update (version 1.0.2.26)</b> - (never approved) Use Dropbox API to circumvent CORB issue; use the chrome.storage API to store OAuth access token.</span><br />
<div>
<br /></div>
<span style="color: #999999;">
<b>2018-02-01 update (version 1.0.2.25)</b> - Rename to "CloudDiff" (formerly "DropboxDiff") with a new Chrome Web Store extension ID -- be sure to update to latest <a href="https://bitbucket.org/vshih/clouddiff-helper/downloads" target="_blank">CloudDiff Helper</a>. <a href="https://www.pcloud.com/" rel="" target="_blank">pCloud</a> support. Switch from jsdifflib to <a href="http://codemirror.net/" rel="" target="_blank">CodeMirror</a> for inline diff.<br />
<br />
<b>2017-04-18 update (version 1.0.2.23)</b> - Update to match latest Dropbox format change.<br />
<br />
<b>2017-03-13 update (versions 1.0.2.21-22)</b> - Bug fix for diffing non-text files, and files larger than 4K; please get latest "CloudDiff Helper".<br />
<br />
<b>2017-01-26 update (version 1.0.2.20)</b> - Implement "Ignore exit status" option.<br />
<br />
<b>2017-01-24 update (versions 1.0.2.17-19)</b> - Updated installation instructions for Mac/Linux; bug fixes.<br />
<br />
<b>2017-01-21 update (version 1.0.2.16)</b> - Support "Load older versions".<br /><br />
</span><br />
<div>
<span style="color: #999999;">...
</span></div>
<span style="color: #999999;">
</span>
</div>
Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com72tag:blogger.com,1999:blog-3062430.post-80905129996688793632011-09-01T16:12:00.000-07:002011-09-01T16:23:35.226-07:00Blame it on the TronI watched old school Tron the other night. So much awesome kitch in that movie, I couldn't stop grinning during the whole thing.
<br />
<br />
<div style="clear: both;">
</div>
Some things I noticed, since last time I watched it, a few decades ago:
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPBBsc1K0d-MhJK0TRpORHv6GiOJqqZaCnpw5YgrPWzmO9NRV9NCPqBn1L4DJKlSSGsfm7H6Dbd-LP1gPBDI0b6ZFTAVXk6GS9fzPu_aIAB0h7whPqf7ydDBj06iEha61KtTt4YQ/s1600/flynns2.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPBBsc1K0d-MhJK0TRpORHv6GiOJqqZaCnpw5YgrPWzmO9NRV9NCPqBn1L4DJKlSSGsfm7H6Dbd-LP1gPBDI0b6ZFTAVXk6GS9fzPu_aIAB0h7whPqf7ydDBj06iEha61KtTt4YQ/s1600/flynns2.jpg" /></a></div>
<div style="clear: both;">
</div>
The "Watseka" street sign sounded really familiar. Lo and behold:
<br />
<br />
<div style="clear: both;">
</div>
<iframe frameborder="0" height="350" marginheight="0" marginwidth="0" scrolling="no" src="http://maps.google.com/maps?f=q&source=embed&hl=en&geocode=&q=Watseka+Avenue,+Los+Angeles,+CA&aq=2&sll=40.776146,-87.736422&sspn=0.103735,0.184364&vpsrc=6&gl=us&g=Watseka,+IL&ie=UTF8&hq=&hnear=Watseka+Ave,+Los+Angeles,+California&ll=34.023985,-118.395259&spn=0.001785,0.00387&z=14&layer=c&cbll=34.022818,-118.39566&panoid=9gDlp1GUsSYiHn8gyvBjbQ&cbp=13,38.21,,0,1.46&output=svembed" width="425"></iframe><br />
<a href="http://maps.google.com/maps?f=q&source=embed&hl=en&geocode=&q=Watseka+Avenue,+Los+Angeles,+CA&aq=2&sll=40.776146,-87.736422&sspn=0.103735,0.184364&vpsrc=6&gl=us&g=Watseka,+IL&ie=UTF8&hq=&hnear=Watseka+Ave,+Los+Angeles,+California&ll=34.023985,-118.395259&spn=0.001785,0.00387&z=14&layer=c&cbll=34.022818,-118.39566&panoid=9gDlp1GUsSYiHn8gyvBjbQ&cbp=13,38.21,,0,1.46" style="color: blue; text-align: left;">View Larger Map</a><br />
<br />
I live within 10 miles of Flynn's! We'll have to pay homage some time. Here's the wider shot.<br />
<br />
<div style="clear: both;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_CO6UudZP9c9J1RF_a_W4lZ_shSab3w29dONrTBWF8EvQ8YvNWIyOEx_tw0cfMC5Bu2cYTPRACRrV3806KO0E0OG4sJWwshXq6_TV-1BO0k5HJg3CBp_O-qJh21msuAySpWmU4g/s1600/flynns1.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_CO6UudZP9c9J1RF_a_W4lZ_shSab3w29dONrTBWF8EvQ8YvNWIyOEx_tw0cfMC5Bu2cYTPRACRrV3806KO0E0OG4sJWwshXq6_TV-1BO0k5HJg3CBp_O-qJh21msuAySpWmU4g/s1600/flynns1.jpg" /></a></div>
<div style="clear: both;">
</div>
I don't think they used the same spot for Tron: Legacy, though.<br />
<br />
<div style="clear: both;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdJbQIqnJsyuT6EirQRwi04gEHi7OYvYOzjTk7ujDYYObs_Ug3O21Ou5vnml3ZP_iyySf4iof9O_hsIOfBQsN_7yjo7_ZoWk6hGhItcuhCSTp0OoaG0hTogz3nTJavNSvMTTwP7g/s1600/flynns3.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdJbQIqnJsyuT6EirQRwi04gEHi7OYvYOzjTk7ujDYYObs_Ug3O21Ou5vnml3ZP_iyySf4iof9O_hsIOfBQsN_7yjo7_ZoWk6hGhItcuhCSTp0OoaG0hTogz3nTJavNSvMTTwP7g/s1600/flynns3.jpg" /></a></div>
<div style="clear: both;">
</div>
I also don't remember this blatant Easter egg:
<br />
<br />
<div style="clear: both;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQ3_pDkGZfeHyi9LR4lKDHI7cgK7O0Nw5RaJM6LJsWbNsPsde64eue5zc6vY0UI2C4EdgsWDnOTUr9Xa6CthS0d5b_c2QHFFoj6tud2QC2Lk-Du3TJ7N1t278IW-TkDabpzLjXPQ/s1600/pacman.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQ3_pDkGZfeHyi9LR4lKDHI7cgK7O0Nw5RaJM6LJsWbNsPsde64eue5zc6vY0UI2C4EdgsWDnOTUr9Xa6CthS0d5b_c2QHFFoj6tud2QC2Lk-Du3TJ7N1t278IW-TkDabpzLjXPQ/s1600/pacman.jpg" /></a></div>
<div style="clear: both;">
</div>
They even sampled the Pac-Man sound effects. I remember Pac-Man being such an incredible craze at the time (we sang the "Pac-Man Fever" song in school once, badly), but somehow I never caught it here.<br />
<br />
The Messianic overtones of the movie were pretty interesting too — Flynn being the User/god, come to inhabit the world of programs in order to save them. I certainly didn't pick that up as an 8-year old. Then again, it's only these days that I spend any time wondering whether our reality is just a computer simulation.<br />
<br />
Here's a bit of dialogue I liked quite a bit. Flynn has just revealed to Tron that he is actually a User, and not just a program, like the rest of them.<br />
<blockquote>
Tron: "If you are a User, then everything you've done has been according to a plan, right?</blockquote>
<blockquote>
Flynn: "You wish! You guys know what it's like; you just keep doing what it looks like you're supposed to be doing, no matter how crazy it seems."</blockquote>
<blockquote>
Tron: "That's the way it is with programs, yes..."</blockquote>
<blockquote>
Flynn: "I hate to disappoint you pal, but most of the time that's the way it is for Users, too."</blockquote>
<blockquote>
Tron: "Stranger and stranger."</blockquote>
Wise words.Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com1Flynn's, Culver City, CA 90232, USA34.0244874 -118.396907534.0211974 -118.401843 34.0277774 -118.391972tag:blogger.com,1999:blog-3062430.post-26324499745921444182011-07-10T15:07:00.000-07:002011-07-10T15:07:41.033-07:00Facebook DisHave you ever been alone, minding your own business, and suddenly realize that someone has been following you, watching your every move, for the past two hours?<br />
<br />
That's what it feels like when I'm visiting different websites and I suddenly see:<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTSecNaz_j-O69TRbWxzL7XjhPXMF79V1rPwI02WF5ogeEZTnhO_MZ9ypRzWoO2IdwXISSONPoLiwblNbE1bJqe_FCysZrrz2agc13z6FRe0nSV9zeWoT3JqUNBz2agkm-tO9m6Q/s1600/wp.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTSecNaz_j-O69TRbWxzL7XjhPXMF79V1rPwI02WF5ogeEZTnhO_MZ9ypRzWoO2IdwXISSONPoLiwblNbE1bJqe_FCysZrrz2agc13z6FRe0nSV9zeWoT3JqUNBz2agkm-tO9m6Q/s1600/wp.png" /></a></div><br />
"<i>[various friends]</i> like this."<br />
<br />
The scary thing is that the stalker metaphor is quite appropriate – Facebook really <i>is</i> stalking you, keeping track of wherever you go whenever you see one of these.<br />
<br />
So I really liked a Chrome extension called <a href="https://chrome.google.com/webstore/detail/ejpepffjfmamnambagiibghpglaidiec">Facebook Disconnect</a>. Unfortunately, it tends to break some sites (Scrabble, in particular). So I extended the extension to allow whitelisting certain sites.<br />
<br />
Presenting: <a href="https://chrome.google.com/webstore/detail/lhjdbhdnelckmkdhebjhgkdiiocdijnm">Facebook Dis</a>.<br />
<br />
If you really want to get fancy you can read the whitelist from a specific URL, say a website or public Dropbox file. This lets you to configure several installations of Facebook Dis in a single place; all instances will stay up to date automatically the next time you open your browser or click "refresh" from the options page.<br />
<br />
Thanks to Brian Kennish for the original Facebook Disconnect.<br />
<div><br />
<div style="clear: both;"></div></div>Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com0tag:blogger.com,1999:blog-3062430.post-19073022031279341562011-03-31T15:53:00.000-07:002019-02-12T10:20:13.000-08:00Fast Make for Vim<b>2019-02-12 update</b> - Added <span style="font-family: "courier new" , "courier" , monospace;"><span class="pl-k" style="background-color: white; box-sizing: border-box; font-size: 12px; white-space: pre;">g:</span><span style="background-color: white; font-size: 12px; white-space: pre;">Make_quickfix_always_open</span></span><span style="background-color: white; color: #24292e; font-family: , "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 12px; white-space: pre;"> option.</span><br />
<b><br /></b>
<b>2014-05-18 update</b> - This is now <a href="https://github.com/vshih/vim-make" target="_blank">vim-make</a> on GitHub.<br />
<br />
I wasn't really satisfied with Vim's :make behavior so I wrote a script to do what I wanted.<br />
<ul>
<li>Saves buffer first<br />
</li>
<li>If there are errors, show them in the quickfix window</li>
<li>Success is reported in the status bar<br />
</li>
<li>Saves some keystrokes, especially if mapped to <code>F5</code><br />
</li>
</ul>
Here it is. You can put it in <code>~/.vim/plugin/Make.vim</code>, or if you are using <a href="http://www.vim.org/scripts/script.php?script_id=2332">pathogen</a>, <code>~/.vim/bundle/Make/plugin/Make.vim</code>.<br />
<br />
This is basically my first Vim plugin so please let me know if there are things I could improve.
<br />
<br />
<div style="background-color: black; color: white; font-family: monospace;">
<span style="color: #80a0ff;">"=============================================================================</span><br />
<span style="color: #80a0ff;">"</span> <span style="color: #ff80ff;">File:</span><span style="color: #80a0ff;"> Make.vim</span><br />
<span style="color: #80a0ff;">"</span> <span style="color: #ff80ff;">Author:</span><span style="color: #80a0ff;"> Victor Shih <victor.shih@gmail.com></span><br />
<span style="color: #80a0ff;">"</span> <span style="color: #ff80ff;">Last Change:</span><span style="color: #80a0ff;"> 2/11/2019</span><br />
<span style="color: #80a0ff;">"</span> <span style="color: #ff80ff;">Version:</span><span style="color: #80a0ff;"> 0.02</span><br />
<span style="color: #80a0ff;">"</span> <span style="color: #ff80ff;">WebPage:</span><span style="color: #80a0ff;"> <a href="http://blog.vicshih.com/2011/03/fast-make-for-vim.html">http://blog.vicshih.com/2011/03/fast-make-for-vim.html</a></span><br />
<span style="color: #80a0ff;">"</span> <span style="color: #ff80ff;">Description:</span><span style="color: #80a0ff;"> Modestly enhanced `make` for Vim.</span><br />
<span style="color: #80a0ff;">"</span><br />
<br />
<span style="color: #ffff60;"><b>function</b></span>! Make<span style="color: orange;">(</span>args<span style="color: orange;">)</span><br />
<span style="color: #80a0ff;"> " Compile arguments.</span><br />
<span style="color: #ffff60;"><b>let</b></span> <span style="color: #40ffff;">l:args</span> <span style="color: #ffff60;"><b>=</b></span> <span style="color: #40ffff;">strlen</span><span style="color: orange;">(</span><span style="color: #40ffff;">a:args</span><span style="color: orange;">)</span> ? <span style="color: #ffa0a0;">' '</span> <span style="color: #ffff60;"><b>.</b></span> <span style="color: #40ffff;">a:args</span> : <span style="color: #ffa0a0;">''</span><br />
<span style="color: #ffff60;"><b>let</b></span> <span style="color: #40ffff;">l:title</span> <span style="color: #ffff60;"><b>=</b></span> <span style="color: #40ffff;">expand</span><span style="color: orange;">(</span><span style="color: #ffa0a0;">'%'</span><span style="color: orange;">)</span> <span style="color: #ffff60;"><b>.</b></span> <span style="color: #ffa0a0;">' - Make'</span> <span style="color: #ffff60;"><b>.</b></span> <span style="color: #40ffff;">l:args</span><br />
<br />
<span style="color: #80a0ff;"> " Force write.</span><br />
<span style="color: #ffff60;"><b>silent</b></span> <span style="color: #ffff60;"><b>update</b></span>!<br />
<br />
<span style="color: #80a0ff;"> " Find the closest directory to the current file with a [Mm]akefile.</span><br />
<span style="color: #ffff60;"><b>let</b></span> <span style="color: #40ffff;">l:makefile_dir</span> <span style="color: #ffff60;"><b>=</b></span> s:find_makefile_dir<span style="color: orange;">()</span><br />
<br />
<span style="color: #80a0ff;"> " Move to that directory and make.</span><br />
<span style="color: #ffff60;"><b>let</b></span> <span style="color: #40ffff;">l:out</span> <span style="color: #ffff60;"><b>=</b></span> <span style="color: #40ffff;">split</span><span style="color: orange;">(</span><span style="color: #40ffff;">system</span><span style="color: orange;">(</span><span style="color: #ffa0a0;">'cd '</span> <span style="color: #ffff60;"><b>.</b></span> l:makefile_dir <span style="color: #ffff60;"><b>.</b></span> <span style="color: #ffa0a0;">' && make'</span> <span style="color: #ffff60;"><b>.</b></span> l:args<span style="color: orange;">)</span>, <span style="color: #ffa0a0;">"\n</span><span style="color: #ffa0a0;">"</span><span style="color: orange;">)</span><br />
<span style="color: #ffff60;"><b>let</b></span> <span style="color: #40ffff;">l:len</span> <span style="color: #ffff60;"><b>=</b></span> <span style="color: #40ffff;">len</span><span style="color: orange;">(</span>l:out<span style="color: orange;">)</span><br />
<br />
<span style="color: #80a0ff;"> " Output to quickfix.</span><br />
<span style="color: #ffff60;"><b>cgetexpr</b></span> <span style="color: #40ffff;">l:out</span><br />
<span style="color: #ffff60;"><b>let</b></span> <span style="color: #40ffff;">w:quickfix_title</span> <span style="color: #ffff60;"><b>=</b></span> <span style="color: #40ffff;">l:title</span><br />
<br />
<span style="color: #ffff60;"><b>if</b></span> <span style="color: #40ffff;">g:Make_quickfix_always_open</span> <span style="color: #ffff60;"><b>==</b></span> <span style="color: #ffa0a0;">1</span> <span style="color: #ffff60;"><b>||</b></span> <span style="color: #40ffff;">l:len</span> <span style="color: #ffff60;"><b>></b></span> <span style="color: #ffa0a0;">1</span><br />
<span style="color: #ffff60;"><b>copen</b></span><br />
<span style="color: #ffff60;"><b>cc</b></span> <span style="color: #ffa0a0;">1</span><br />
<span style="color: #ffff60;"><b>elseif</b></span> <span style="color: #40ffff;">l:len</span> <span style="color: #ffff60;"><b>==</b></span> <span style="color: #ffa0a0;">0</span><br />
<span style="color: #80a0ff;"> " No output; just report success.</span><br />
<span style="color: #ffff60;"><b>cclose</b></span><br />
<span style="color: #ffff60;"><b>redraw</b></span><br />
<span style="color: #ffff60;"><b>echo</b></span> <span style="color: #40ffff;">l:title</span> . <span style="color: #ffa0a0;">' succeeded'</span><br />
<span style="color: #ffff60;"><b>else</b></span><br />
<span style="color: #80a0ff;"> " Output is a single line; echo it.</span><br />
<span style="color: #ffff60;"><b>cclose</b></span><br />
<span style="color: #ffff60;"><b>cc</b></span> <span style="color: #ffa0a0;">1</span><br />
<span style="color: #ffff60;"><b>redraw</b></span><br />
<span style="color: #ffff60;"><b>echo</b></span> <span style="color: #40ffff;">l:out</span>[0]<br />
<span style="color: #ffff60;"><b>endif</b></span><br />
<span style="color: #ffff60;"><b>endfunction</b></span><br />
<br />
<br />
<span style="color: #ffff60;"><b>function</b></span> <span style="color: orange;">s:</span>find_makefile_dir<span style="color: orange;">()</span><br />
<span style="color: #ffff60;"><b>let</b></span> <span style="color: #40ffff;">l:dir</span> <span style="color: #ffff60;"><b>=</b></span> <span style="color: #40ffff;">expand</span><span style="color: orange;">(</span><span style="color: #ffa0a0;">'%:p:h'</span><span style="color: orange;">)</span><br />
<br />
<span style="color: #ffff60;"><b>while</b></span> <span style="color: #ffa0a0;">1</span><br />
<span style="color: #80a0ff;"> " Ensure we have only one '/'.</span><br />
<span style="color: #ffff60;"><b>if</b></span> !<span style="color: #40ffff;">empty</span><span style="color: orange;">(</span><span style="color: #40ffff;">glob</span><span style="color: orange;">(</span><span style="color: #40ffff;">substitute</span><span style="color: orange;">(</span>l:dir, <span style="color: #ffa0a0;">'/$'</span>, <span style="color: #ffa0a0;">''</span>, <span style="color: #ffa0a0;">''</span><span style="color: orange;">)</span> <span style="color: #ffff60;"><b>.</b></span> <span style="color: #ffa0a0;">'/[Mm]akefile'</span><span style="color: orange;">))</span><br />
<span style="color: #ffff60;"><b>return</b></span> <span style="color: #40ffff;">l:dir</span><br />
<span style="color: #ffff60;"><b>else</b></span><br />
<span style="color: #ffff60;"><b>let</b></span> <span style="color: #40ffff;">l:parent</span> <span style="color: #ffff60;"><b>=</b></span> <span style="color: #40ffff;">fnamemodify</span><span style="color: orange;">(</span>l:dir, <span style="color: #ffa0a0;">':h'</span><span style="color: orange;">)</span><br />
<span style="color: #ffff60;"><b>if</b></span> <span style="color: #40ffff;">l:parent</span> <span style="color: #ffff60;"><b>==#</b></span> <span style="color: #40ffff;">l:dir</span><br />
<span style="color: #80a0ff;"> " We reached the root but didn't find a Makefile.</span><br />
<span style="color: #ffff60;"><b>return</b></span> <span style="color: #ffa0a0;">'.'</span><br />
<span style="color: #ffff60;"><b>endif</b></span><br />
<br />
<span style="color: #ffff60;"><b>let</b></span> <span style="color: #40ffff;">l:dir</span> <span style="color: #ffff60;"><b>=</b></span> <span style="color: #40ffff;">l:parent</span><br />
<span style="color: #ffff60;"><b>endif</b></span><br />
<span style="color: #ffff60;"><b>endwhile</b></span><br />
<span style="color: #ffff60;"><b>endfunction</b></span><br />
<br />
<br />
<span style="color: #80a0ff;">" Register command.</span><br />
<span style="color: #ffff60;"><b>command</b></span>! <span style="color: #ffff60;"><b>-</b></span><span style="color: #ff80ff;">nargs</span><span style="color: #ffff60;"><b>=?</b></span> Make <span style="color: #40ffff;">call</span> Make(<span style="color: #ffa0a0;">"<args></span><span style="color: #ffa0a0;">"</span>)<br />
<br />
<span style="color: #ffff60;"><b>let</b></span> <span style="color: #40ffff;">g:Make_quickfix_always_open</span> <span style="color: #ffff60;"><b>=</b></span> <span style="color: #40ffff;">get</span><span style="color: orange;">(</span>g:, <span style="color: #ffa0a0;">'Make_quickfix_always_open'</span>, <span style="color: #ffa0a0;">'0'</span><span style="color: orange;">)</span><br />
<span style="color: #ffff60;"><b>let</b></span> <span style="color: #40ffff;">g:Make_loaded</span> <span style="color: #ffff60;"><b>=</b></span> <span style="color: #ffa0a0;">1</span><br />
<br /></div>
Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com0tag:blogger.com,1999:blog-3062430.post-19309000184157397382010-11-29T09:04:00.000-08:002010-11-29T09:04:11.089-08:00Ruby AutoflushGoogle seems to need help with this particular association, so here goes.<br />
<br />
In Ruby, to flush currently buffered data just once, call <code>flush</code> on the handle in question:<br />
<blockquote><code>STDOUT.flush</code></blockquote>To "autoflush", or continuously flush output immediately, set the <code>sync</code> attribute:<br />
<blockquote><code>STDOUT.sync = true</code></blockquote>References: <a href="http://ruby-doc.org/core/classes/IO.html#M002278">flush</a>, <a href="http://ruby-doc.org/core/classes/IO.html#M002263">sync</a>Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com1tag:blogger.com,1999:blog-3062430.post-14240229637157130102010-04-25T22:37:00.000-07:002010-07-24T11:50:35.539-07:00Keyboard Shortcuts for Facebook Photo TaggingFinally got around to tagging some photos in Facebook. I probably would not have bothered, had <a href="http://thegleebox.com/">gleeBox</a> not made it a bit tolerable by providing some form of keyboard shortcuts for the process:<br /><ul><li>Created an "ESP vision" for the Page URL<blockquote><code>facebook.com/photo.php</code></blockquote>with the jQuery selector<br /><blockquote><code>#photoactions>a[onclick],input[type="submit"]<br /><s>#photoactions>a:first-child,input[type="submit"]</s></code></blockquote></li><br /><li>Changed my "Shortcut to launch gleeBox" to ";"</li></ul><br />This allows tagging to go as follows:<br /><ul><li>Navigate to a Facebook photo album</li><br /><li>Press <b><code>;<ENTER></code></b> with left hand to enter tagging mode</li><br /><li>Tag at will</li><br /><li>Press <b><code>;<ENTER></code></b> again to leave tagging mode</li><br /><li>Left-click photo to move to the next photo</li><br /></ul>With the target crosshairs, it's about as close to an FPS you can get.<br /><br /><b>7/24/10 Update</b>: Updated to skip new "Share" link.Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com0tag:blogger.com,1999:blog-3062430.post-14227687482950929942010-04-15T12:41:00.000-07:002010-04-15T12:49:52.484-07:00Mac Remote Desktop Connection Keyboard ShortcutsTo send the three-finger salute, <code>Ctrl+Alt+Del</code>, to a Windows box when you are connected using a Mac via Microsoft's Remote Desktop Connection, try <code>Ctrl+Option+Delete</code> (<code>backspace</code>).Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com0tag:blogger.com,1999:blog-3062430.post-52177003972050718862010-04-04T21:48:00.000-07:002010-04-04T22:31:26.161-07:00Edit "Save Password" Exceptions in Google Chrome for Mac OS XIf you're a Google Chrome for Mac OS X user and you've ever hit "Never for this site" by accident (or have girlfriend who does so consistently), it's a little tricky finding out how to edit these "Save Password" exceptions. It's pretty clear for Windows' Chrome:<br /><br /><a href="http://www.google.com/support/chrome/bin/answer.py?hl=en&answer=156325">http://www.google.com/support/chrome/bin/answer.py?hl=en&answer=156325</a><br /><br />but I had trouble finding a solution for the Mac. A little snooping reveals that Chrome keeps its login information in a SQLite database file:<blockquote><code><b>~/Library/Application Support/Google/Chrome/Default/Login Data</b></code></blockquote>To remove an entry from the exception list, do the following:<ol><li>Shut down Chrome</li><br /> <li>Probably a good idea to make a backup of the database file</li><br /> <li>Open the database file in a SQLite database browser; I use <a href='http://sqlitebrowser.sourceforge.net/'>SQLite Database Browser</a></li><br /> <li>Select the "Browse Data" tab</li><br /> <li>Sites for which "Never for this Site" has been selected will have the value <code>1</code> for the column <code>blacklisted_by_user</code>. Double-click the desired cell, change the value to <code>0</code>, and click "Apply Changes"</li><br /> <li>Save and close the database file</li><br /> <li>Restart Chrome</li><br /></ol>Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com20tag:blogger.com,1999:blog-3062430.post-65260000877008829212009-04-27T09:49:00.000-07:002011-02-06T23:19:46.199-08:00Ubiquity - Bugmenot commandI like to use <a href='http://www.bugmenot.com'>BugMeNot</a> when trying to access some websites which require registration, most frequently the New York Times.<br />
<br />
Bugmenot has a bookmarklet, but it opens a new window, and is therefore slow, and you have to copy and paste login information yourself.<br />
<br />
<a href='https://wiki.mozilla.org/Labs/Ubiquity'>Ubiquity</a> is a command line interface to various things for Firefox.<br />
<br />
I've created a <a href='http://gist.github.com/102363'>Bugmenot command for Ubiquity</a>.<br />
<br />
Simply execute <code>bugmenot</code> while viewing the desired login page, and the top-ranked Bugmenot entry will be populated and submitted.<br />
<br />
If that login has expired, you can specify an entry number as a parameter, from the list of entries in the Ubiquity preview pane.<br />
<br />
Get it at <a href='http://gist.github.com/102363'>http://gist.github.com/102363</a>.<br />
<br />
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG-VqVV-tYWOFspdGx7Uljz9h_D8lMeebpKBdR2-hCn2mFyfH0KUHseMYbc_SpI1ZH2Blkt61DMfVQYhDsndwDv2QyPljDxa-sNmF1VioE5o-8oU6uGMhzPTi1DDU6YzlDQMfXVg/s1600-h/gr.png"><img style="float:left; margin:0 10px 10px 0; cursor:pointer; cursor:hand;width: 320px; height: 208px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG-VqVV-tYWOFspdGx7Uljz9h_D8lMeebpKBdR2-hCn2mFyfH0KUHseMYbc_SpI1ZH2Blkt61DMfVQYhDsndwDv2QyPljDxa-sNmF1VioE5o-8oU6uGMhzPTi1DDU6YzlDQMfXVg/s320/gr.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5329423504316582802" /></a><br />
<div style='clear: both'></div><br />
Some code was borrowed from <a href='http://www.yalazi.org/ubiquity/list.html'>Onur Yalazı</a> and Brandon Goldsworthy.<br />
<br />
<b>7/9/09 update</b>: Updated to support Ubiquity's Parser 2. The old code is still available <a href='http://gist.github.com/102363/39ebf2b60bf3db2a5c9cd80c334526dd71f899ae'>here</a>.Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com1tag:blogger.com,1999:blog-3062430.post-12280220052591255772009-01-02T18:47:00.000-08:002009-07-23T00:17:28.147-07:00Fix for Firefox’s Password Exporter Add-on<b>7/23/09 Update</b>: Updated to be compatible up to Firefox 3.5.1.<br /><br /><b>1/8/09 Update</b>: If you tried installing the .xpi and got “Firefox could not install the file at [...] because: Not a valid install package -207,” please see the revised download instructions below.<br /><br /><br />I like Firefox’s <a href="https://addons.mozilla.org/en-US/firefox/addon/2848">Password Exporter Add-on</a>, but recently I noticed a bug with version 1.1 (released January 5, 2008) when importing into Firefox 3. Several entries return the following error:<br /><br /><blockquote>'Can't add a login with both a httpRealm and formSubmitURL.' when calling method: [nsILoginManager::addLogin]</blockquote><br /><br />I’ve posted the .xpi at <a href="http://www.vicshih.com/files/password_exporter-1.1-fx_tb-formSubmitURL-fix.xpi"> http://www.vicshih.com/files/password_exporter-1.1-fx_tb-formSubmitURL-fix.xpi</a> (90.1KB).<br /><br /><strike>Right-click and</strike> Left-click this link, which should prompt Firefox to download to your machine. My web page does a redirect, so right-clicking directly actually saves an intermediate web page, which is not what you want. If in doubt, make sure file size is correct. Drag to a browser window to install.<br /><br />Here’s the diff, in case you are queasy about installing my unsigned version.<br /><br />Within the file <code>chrome/content/passwordexporter.jar</code>, in the file <code>content/pwdex-loginmanager.js</code>,<br /><br /><pre><br />540,541c540,549<br />< <br />< var bogusLoginInfo = new nsLoginInfo(entries[i].hostname, 'http://passwordexporter',<br />---<br />> var doModify = false;<br />><br />> var formSubmitURL = entries[i].formSubmitURL;<br />><br />> if (formSubmitURL) {<br />> formSubmitURL = '';<br />> doModify = true;<br />> }<br />><br />> var bogusLoginInfo = new nsLoginInfo(entries[i].hostname, formSubmitURL,<br />548c556<br />< loginManager.modifyLogin(bogusLoginInfo, entries[i]);<br />---<br />> if (doModify) loginManager.modifyLogin(bogusLoginInfo, entries[i]);<br /></pre>Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com22tag:blogger.com,1999:blog-3062430.post-83328977207243666712008-11-04T22:40:00.000-08:002008-11-05T06:35:48.397-08:00Shortcut to Toggle Firefox Bookmarks Toolbar (like Chrome)One of the things I've really liked about Google Chrome is the ability to toggle the bookmarks toolbar with a quick <code>Ctrl+B</code>. I hunted around for this ability in Firefox but it took a little finagling -- here's the how-to:<br /><ul><br /> <li>Install <a href="http://forums.mozillazine.org/viewtopic.php?t=72994">Keyconfig</a>.</li><br /> <li>Open Keyconfig's configuration dialog via "Tools | Keyconfig..." or <code>Ctrl+Shift+F12</code>.</li><br /> <li>If you want to use <code>Ctrl+B</code> to toggle the Bookmarks Toolbar, first disable the default association to "Bookmarks" by selecting it and clicking the "Disable" button.</li><br /> <li>Click the "Add a new key" button and fill out the form using the following:<br /> <ul><br /> <li><b>Name:</b> <code>Toggle Bookmarks Toolbar</code></li><br /> <li><b>Code:</b><pre>var b = document.getElementById('PersonalToolbar');<br />b.collapsed = !b.collapsed;</pre></li></ul></li><div style='clear: both'></div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga-C6nzbU8TaYfLzQJAX-GcAJSqJdApUc3wtCXsIrqAadDcPdrAD3m0j92a5K-BOF_SbUzHUqQ1XlhE7T9qYKyaxhZvvsev1TnA4j1akmrsGyznjwd9SvvYsCC6rO2hF8SH10w_g/s1600-h/keyconfig1.PNG"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 335px; height: 260px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga-C6nzbU8TaYfLzQJAX-GcAJSqJdApUc3wtCXsIrqAadDcPdrAD3m0j92a5K-BOF_SbUzHUqQ1XlhE7T9qYKyaxhZvvsev1TnA4j1akmrsGyznjwd9SvvYsCC6rO2hF8SH10w_g/s400/keyconfig1.PNG" alt="" id="BLOGGER_PHOTO_ID_5265068774987867410" border="0" /></a><div style="clear: both;"></div><br /> <li>Click "OK."</li><br /> <li>Select your new key, select the text field, type your desired shortcut (<code>Ctrl+B</code>, for example), and click "Apply."<div style='clear: both'></div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCSw4qyoKqIThTlyqvjT8lzPmTT92K3xEKZ9uV3D77p7fGI8LZLlG4XXa-H6bEMU6K-BmfvvUCWq-Y6VVi3vFWbJGJlOmCaDwg3ZPgL5crVFrn8hvez13hCXHK9fg4KVhQS2i3yw/s1600-h/keyconfig.PNG"><img style="margin: 0pt 10pt 10px 0px; float: left; cursor: pointer; width: 338px; height: 304px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCSw4qyoKqIThTlyqvjT8lzPmTT92K3xEKZ9uV3D77p7fGI8LZLlG4XXa-H6bEMU6K-BmfvvUCWq-Y6VVi3vFWbJGJlOmCaDwg3ZPgL5crVFrn8hvez13hCXHK9fg4KVhQS2i3yw/s400/keyconfig.PNG" alt="" id="BLOGGER_PHOTO_ID_5265067353254700354" border="0" /></a><div style="clear: both;"></div></li></ul>Your shortcut will be active in the next window opened. Yay nerdiness!<br /><br />Another key I've added is a shortcut to toggle the status bar. Here's the code:<pre>var s = document.getElementById('status-bar');<br />s.hidden = !s.hidden;</pre> Enjoy!Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com21tag:blogger.com,1999:blog-3062430.post-69891335792756930822008-04-12T15:56:00.000-07:002008-10-15T08:48:55.675-07:00Todoist Sidebar - Firefox Add-On<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfFgjTTc6_e5ezNhyphenhyphenv8jr1zyXno-0LuR_bY5O-1qCrO-XJPyuEtbov-Juvt8T_MLVZXNLBUKdX_Dmv_blDkOowI_22yPEvyfonUaumkkgIz02hOGrLaJO8bcLh1PMXVNNZsGeSMA/s1600-h/1-login.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfFgjTTc6_e5ezNhyphenhyphenv8jr1zyXno-0LuR_bY5O-1qCrO-XJPyuEtbov-Juvt8T_MLVZXNLBUKdX_Dmv_blDkOowI_22yPEvyfonUaumkkgIz02hOGrLaJO8bcLh1PMXVNNZsGeSMA/s320/1-login.png" alt="" id="BLOGGER_PHOTO_ID_5188492976280066594" border="0" /></a><b>Note</b>: please see the latest <a href='#10_15_08_update'>update</a>.<br /><br />I recently switched from Google Notebook to <a href="http://todoist.com/">Todoist</a> for my to-do lists. I'd searched a while for a list manager that could do hierarchical tasks, and Todoist looks like the only one that does, at least for free. It does hierarchical projects too, in fact.<br /><br />One hack I saw on their site described a way to load Todoist into Firefox's sidebar, basically by bookmarking a <a href="http://todoist.com/?mini=1">simplified view</a> of the site and checking "Load this bookmark in the sidebar." Nice!<br /><br />My joy soon soured though, when I noticed that adding a task has the side-effect of loading the Todoist website into the main browser window, browsing over whatever site you already have in the current tab. Not so nice.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnMBhmnoq_Oi-5o-pjwLJQfpW4qsEIYwl6-X5ZsLhWYqzO-_j0zpUZ2TY_13qLWkk3l76ZUYT7Yl5OzqGnx1TGiV1QtuPsVXC5GKTU4Hq5c-KkXyG6DPzjCC6VHOPmceiBPg46mg/s1600-h/2-list.png"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnMBhmnoq_Oi-5o-pjwLJQfpW4qsEIYwl6-X5ZsLhWYqzO-_j0zpUZ2TY_13qLWkk3l76ZUYT7Yl5OzqGnx1TGiV1QtuPsVXC5GKTU4Hq5c-KkXyG6DPzjCC6VHOPmceiBPg46mg/s320/2-list.png" alt="" id="BLOGGER_PHOTO_ID_5188492976280066610" border="0" /></a>Plus, I don't like the fact the button to open the sidebar (really just a bookmark) doesn't toggle -- to close the sidebar, you have to mouse <em>all the way over to the sidebar's close button</em>! Ridiculous! And though you can define a keyword for the bookmark which allows easy access through the address bar, there's no way to define a keyboard shortcut to hide the sidebar.<br /><br />So, I put together a Firefox add-on which solves these problems, which I have creatively christened Todoist Sidebar.<br /><br />Some perhaps non-obvious things to note:<br /><ul><br /> <li><span style="font-weight: bold;">Left-click</span> the toolbar button to toggle the Todoist sidebar.<br /> </li><li><span style="font-weight: bold;">Middle-click</span> the toolbar button to open Todoist in a new tab.<br /> </li><li>The default keyboard shortcut is <code><span style="font-weight: bold;">Alt+Shift+2</span></code> on Windows and Linux, and <code><span style="font-weight: bold;">Cmd+Shift+2</span></code> on the Mac.<br /> </li><li>The keyboard shortcut can be <span style="font-weight: bold;">customized</span> by modifying the string values<br /><code>todoist-sidebar.key</code> and <code>todoist-sidebar.modifiers</code> in <code>about:config</code>, according to Mozilla's <a href="http://developer.mozilla.org/en/docs/XUL:key">XUL:key specification</a>. A Firefox restart is required for the changes to take effect. Setting either of these values to blank disables the keyboard shortcut.<br /></li></ul><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYbJtmAfFd2HCDZ83N4VXoDwkhO2lTAn00wvHVaNOf4KLYFO2dql7ry8DPCCTkF8v8q8sd6WSxersjh_RdCnpvHf6EEcdKKLzvSCiug7viWo3d9oEQuuC7XUAtSOYKtAMA-Yr9yg/s1600-h/3-add-item.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYbJtmAfFd2HCDZ83N4VXoDwkhO2lTAn00wvHVaNOf4KLYFO2dql7ry8DPCCTkF8v8q8sd6WSxersjh_RdCnpvHf6EEcdKKLzvSCiug7viWo3d9oEQuuC7XUAtSOYKtAMA-Yr9yg/s320/3-add-item.png" alt="" id="BLOGGER_PHOTO_ID_5188492980575033922" border="0" /></a>All of this will probably be moot once Google continues their world conquest by rolling out their Calendar tasks implementation. But hey, it will be fun while it lasts...<br /><br />Right now the add-on is hosted in the <a href="https://addons.mozilla.org/en-US/firefox/addon/7007">Firefox add-on sandbox</a>.<br /><br /><a name='10_15_08_update'></a><br /><b>10/15/08 update</b>: Okay, Amir, the creator of Todoist, contacted me a bit ago all the way from Denmark to collaborate on the Todoist Sidebar, and he has updated it and now maintains it on the Todoist website! He blogged about it at <a href='http://amix.dk/blog/viewEntry/19333'>http://amix.dk/blog/viewEntry/19333</a>. Please go there to install. Woohoo!<br /><br /><b>5/15/08 update</b>: Hm, it seems to still exhibit the naughty toggle behavior described in the comments on initial install. Restarting Firefox makes the problem go away. I'll look into this at some point. Lame!<br /><br /><b>4/28/08 update</b>: Version 1.0.2 fixes the previously mentioned bug where any key press triggers the sidebar. Also the default key accelerator is now <code>Alt+Shift+2</code> for Windows and Linux, and <code>Cmd+Shift+2</code> for the Mac.<br /><br /><b>4/26/08 update</b>: Please note that currently there is a bug with the default installation where every key press toggles the sidebar (see comments). This is due to my incorrectly implementing the default shortcut key. Also, the intended default is a bit problematic because it tends to interfere with the Tools menu accelerator.<br /><br />I plan to change the default to <code>Alt+Shift+2</code> (<code>Cmd+Shift+2</code> on the Mac) when I get the chance. In the meantime, you can do this yourself by setting <code>todoist-sidebar.key</code> to "<b>2</b>" and <code>todoist-sidebar.modifiers</code> to "<b>alt shift</b>" for Windows/Linux or "<b>accel shift</b>" for the Mac in <code>about:config</code>.<br /><br /><b>4/24/08 update</b>: Please note that some users are experiencing behavior where every key they type (or some subset) toggles the sidebar (see comments). This may possibly be remedied by fiddling with the <code>todoist-sidebar.modifiers</code> setting in <code>about:config</code>. Please be patient and I'll look into this shortly.Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com8tag:blogger.com,1999:blog-3062430.post-66103237611744949962008-04-08T03:06:00.000-07:002010-02-23T19:18:43.535-08:00Move to Trash from the Mac Command LineI was about to make a lengthy comment to a <a href="http://lifehacker.com/software/geek-to-live/useful-command-line-tricks-for-mac-users-302197.php">post</a> on <a href="http://lifehacker.com/">Life Hacker</a> and decided to put most of it here instead. That site is seriously starting to take over my life.<br /><br />A while back I wrote this shell function to be able to move files to the trash from the command line on my Mac, rather than condemning them to oblivion with no chance of return. This is in my <code>.profile</code>.<br /><br />It's a little hairy looking but it does the job. Note that it attempts to append names with a date stamp if a file/directory with that name already exists in the trash, just as the Finder does.<br /><pre>function del() {<br /> while [ -n "$1" ]; do<br /> if [ ! -e "$1" ]; then<br /> echo "'$1' not found; exiting"<br /> return<br /> fi <br /><br /> local file=`basename -- "$1"`<br /><br /> # Chop trailing '/' if there<br /> file=${file%/}<br /><br /> local destination=''<br /><br /> if [ -e "$HOME/.Trash/$file" ]; then<br /> # Extract file and extension<br /> local ext=`expr "$file" : ".*\(\.[^\.]*\)$"`<br /> local base=${file%$ext}<br /><br /> # Add a space between base and timestamp<br /> test -n "$base" && base="$base "<br /><br /> destination="/$base`date +%H-%M-%S`_$RANDOM$ext"<br /> fi <br /><br /> echo "Moving '$1' to '$HOME/.Trash$destination'"<br /> \mv -i -- "$1" "$HOME/.Trash$destination" || return<br /> shift<br /> done<br />}<br /><br />alias rm='del'</pre>An interesting side-effect is that<br /><pre>rm <directory></pre> works as well, which is a little uncanny because ordinarily either <code>rmdir <directory></code> (for an empty directory) or <code>rm -rf</code> is required.<br /><br /><b>2/23/10 update</b>: Handle case where rm options are mistakenly specified.<br /><br /><b>7/4/08 update</b>: Fixed problem when removing file names containing spaces.Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com5tag:blogger.com,1999:blog-3062430.post-84093032606441631422008-04-07T10:34:00.000-07:002008-05-03T02:57:44.533-07:00ApologiesSorry, I can't get enough of reading my own type (and corrections). I replied to <a href="http://www.xanga.com/SonOfPethuel/643819708/item.html">SonOfPethuel's blog</a>.Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com0tag:blogger.com,1999:blog-3062430.post-43563106111598123992008-04-04T19:39:00.000-07:002008-05-03T02:46:12.594-07:00Create Firefox Multiple-Item Packages - maddon.pyI have a (growing) list of Firefox add-ons that I use all the time, so whenever I am customizing a clean machine, it's a tedious process browsing to each add-on's page and going through the installation procedure repeatedly.<br /><br />I learned that the Mozilla framework supports Multiple-Item Packages -- multiple add-ons and/or themes grouped together in a single file. I've written a Python script which takes a list of add-ons and themes in any format I could think of and generates a multiple-item package for you -- <a href="http://www.vicshih.com/files/maddon.py">maddon.py</a>, for "multiple add-on." You can pass to it:<ul><br /><li>local .xpi/jar files<br /><li>directories of .xpi/jar files<br /><li>text files, with each line containing a .xpi/jar file<br /><li>remote URLs<br /><li>websites which will get scraped for .xpi/jar files<br /></ul><br />I use the text file <a href="http://www.vicshih.com/files/VicsAddons.txt">VicsAddons.txt</a> to generate my personal add-on favorites:<br /><pre># Download Statusbar<br />https://addons.mozilla.org/en-US/firefox/addon/26<br /># Google Browser Sync<br />http://tools.google.com/firefox/browsersync/install.html<br /># CustomizeGoogle<br />https://addons.mozilla.org/en-US/firefox/addon/743<br /># Better Gmail 2<br />http://lifehacker.com/software/exclusive-lifehacker-download/better-gmail-2-firefox-extension-for-new-gmail-320618.php<br /># Better GCal<br />http://lifehacker.com/software/exclusive-lifehacker-download/enhance-google-calendar-with-the-better-gcal-firefox-extension-260074.php<br /># Better GReader<br />http://lifehacker.com/software/exclusive-lifehacker-download/trick-out-google-reader-with-better-greader-262020.php<br /># Adblock<br />https://addons.mozilla.org/en-US/firefox/addon/10<br /># dragdropupload<br />https://addons.mozilla.org/en-US/firefox/addon/2190<br /># Firebug<br />http://getfirebug.com/<br /># Google Gears<br />http://dl.google.com/gears/current/gears-osx-opt.xpi<br /># PicLens<br />http://www.piclens.com/site/firefox/tutorial_pl_ff.php</pre><br />Running it produces the following output:<br /><pre>$ maddon.py VicsAddons.txt<br />Parsing 'VicsAddons.txt'<br />Parsing 'https://addons.mozilla.org/en-US/firefox/addon/26'<br />Scanning page...<br />Downloading 'https://addons.mozilla.org/en-US/firefox/downloads/file/24860/download_statusbar-0.9.6.1-fx.xpi'<br />Adding 'download_statusbar-0.9.6.1-fx.xpi'<br />Parsing 'http://tools.google.com/firefox/browsersync/install.html'<br />Scanning page...<br />Downloading 'http://dl.google.com/firefox/google-browsersync.xpi'<br /> ...<br /><br />Created 'VicsAddons.xpi' with the following files:<br />download_statusbar-0.9.6.1-fx.xpi<br />google-browsersync.xpi<br />customizegoogle-0.71-fx+sm.xpi<br />bettergmail2_0.3.4.xpi<br />bettergcal_0.2.2.xpi<br />bettergreader_0.2.2.xpi<br />adblock-0.5.3.043-fx+fl+mz+ns.xpi<br />dragdropupload-1.5.25-fx.xpi<br />firebug1.0-current.xpi<br />firebug-1.1.0b12.xpi<br />gears-osx-opt.xpi<br />piclens-mac-release-1.6.2.1659.xpi<br />install.rdf</pre><br />I can then drag <code>VicsAddons.xpi</code> to a Firefox window, and all add-ons and themes are installed in one fell swoop (restarting Firefox still required, unfortunately).<br /><br />Note that since Firebug has both its current and beta versions on the same web page, <code>maddon.py</code> adds them both, which could be problematic. I could reference the exact desired .xpi version, but this loses the benefit of retrieving the latest version when run. Ah, trade-offs.<br /><br />Here is the help.<br /><br /><pre>usage: maddon.py [options] <file_or_directory> [...]<br /><br />Create a multiple-item XPI. The <file_or_directory> argument(s) can be any of the following:<br /><br /> .(xpi|jar) file - added directly to bundle<br /> URL, .webloc file<br /> - if ends with '.(xpi|jar)', will be downloaded and add to bundle;<br /> otherwise, the web page is scanned for links ending with '.(xpi|jar)'<br /> directory - scanned for files satisfying any of the above requirements<br /> text file - each line is scanned as if it were given as a parameter. Lines beginning<br /> with '"', '#', '!', or ':' are considered comments</pre>Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com0tag:blogger.com,1999:blog-3062430.post-70591580014337885142008-03-28T11:00:00.000-07:002008-05-03T02:46:12.594-07:00Find Duplicate Files - dups.pyI have a lot of images imported at different times and from different sources, and I wanted a quick way to find duplicates. Not finding a satisfactory (read: free) solution (though I admittedly didn't do a very exhaustive search), I took this opportunity to learn Python and came up with <a href="http://www.vicshih.com/files/dups.py">dups.py</a>. Note that the file displays within a frame, so you might have to view frame source to get to the actual code.<br /><br />Without arguments, <code>dups.py</code> checks the current directory, recursively:<br /><pre>$ dups.py<br />Duplicates found:<br />./Data/2004/05_4/015_12A.jpg<br />./Data/2004/2004.09.29 Grandma/015_12A.jpg<br />Duplicates found:<br />./Data/2002/19/uvs021219-008.jpg<br />./Data/2006/01_2/uvs040430-006.jpg<br /> ...</pre>This has been tested on the Mac OS X and cygwin, and should also work with Python for Windows.<br /><br />There are lots of nerdy options, like filtering by file size and following symbolic links. Try <code>dups.py -h</code> to see them all:<br /><pre>usage: dups.py [options] [<file_or_directory> ...]<br /><br />Find duplicate files in the given path(s). Defaults to searching files recursively,<br />except for hidden files (beginning with "."), empty files, and symbolic links.<br /><br />Options:<br /> --version show program's version number and exit<br /> -h, --help show this help message and exit<br /> -v, --verbose verbose<br /><br /> Exclusion Options:<br /> -f, --flat do not scan directories recursively<br /> -g n, --greater-than=n<br /> only scan files of size greater than n bytes<br /> -l n, --less-than=n<br /> only scan files of size less than n bytes<br /><br /> Inclusion Options:<br /> -L, --follow-links follow symbolic links (warning: beware of infinite<br /> loops)<br /> -H, --hidden-files include hidden files<br /> -z, --zero-files include empty files<br /><br /> Miscellaneous:<br /> -D, --delete delete subsequent duplicates (files are scanned in<br /> argument-list order)<br /> -c, --create-rel-links<br /> replace subsequent duplicates with relative links<br /> (non-Windows only)<br /> -C, --create-abs-links<br /> same as "-c", but links are absolute<br /> -s, --special-hidden<br /> changes meaning of "hidden files" (-H) depending on<br /> platform: cygwin - uses Windows file attributes<br /> (warning: slow); win32 - files with names starting<br /> with "." considered hidden<br /></pre><br />P.S. I hacked together a way to detect Windows hidden files from cygwin but it's ugly and slow.<br /><br /><b>4/6/08 update</b>: I added the ability to delete duplicates (-D), and create relative (-c) or absolute (-C) symbolic links.Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com2tag:blogger.com,1999:blog-3062430.post-55532655225009491052008-03-01T17:06:00.000-08:002008-05-03T02:46:12.595-07:00Hacking Lite - Evading Coffee Shop BannersThis is mostly a note to myself and not intended to express approval of the behavior described ;-)<br /><br />Occasionally I like to bring my laptop to a nearby coffee shop to get some work done without all of the distractions of my apartment. My favorite place has been a <a href="http://losangeles.citysearch.com/profile/32776025/">Tanner's Coffee Company</a> within walking distance of my place. It's a little noisy sometimes, and the food isn't the freshest, but the drinks are decent and I seem to get a lot done whenever I'm there.<br /><br />Their wireless offering injects an ad banner at the top of every page. This alone would not be prohibitively annoying since adblock successfully strips the ads, leaving only the banner, but what does tend to dampen the customer experience is that it breaks some sites, Google Reader in particular. Because of this, I started to do a little tinkering...<br /><br />I figured they didn't inject all internet traffic, since I'm able to ssh without problems. Maybe they detect requests to servers at port 80? I toyed with the idea of using a local proxy server, blah blah blah...<br /><br />Turns out, they actually filter on the user agent field within HTTP requests! This means that if you're using Firefox or Safari (or, I imagine, Internet Explorer), the banner will be injected; Opera, however, is ad-free. This also means that simply changing the user agent field that your browser declares in its HTTP requests sets you (ad) free as well.<br /><br />In Firefox there are a number of ways to do this: install a <a href="https://addons.mozilla.org/en-US/firefox/addon/59">Firefox extension</a>, or simply add a string value to <code>about:config</code> named:<br /><br /><code>general.useragent.override</code><br /><br />with a value like<br /><br /><code>Opera/9.26 (Macintosh; Intel Mac OS X; U; en)</code><br /><br />as described <a href="http://johnbokma.com/mexit/2004/04/24/changinguseragent.html">here</a>. It's probably a good idea to stick with a realistic user agent string as opposed to something arbitrary, since websites like Gmail may switch to less functional versions if they don't recognize your browser.<br /><br />A quick way to determine your browser's user agent is <a href="javascript:document.write(navigator.userAgent)" target="_new">javascript:document.write(navigator.userAgent)</a>.<br /><br />The service responsible for the ads at this particular Tanner's (I think they're all independently owned) seems to be a company named <a href="http://box.anchorfree.net/ad-free.php?tag=AFGL00001100">AnchorFree</a>. Chances are, this technique could work for ad-injection schemes used by other wi-fi spots.<br /><br />Done and done. Back to high-quality coffee shop web surfing!<br /><br /><b>5/1/08 update</b>: Okay, I'm dumb. A much easier way to do this is to add the filter<br /><br />*.anchorfree.*<br /><br />in <a href="https://addons.mozilla.org/en-US/firefox/addon/1865">AdBlock Plus</a>. This solves the problem much more elegantly and doesn't run into issues with sites not supporting your supposed user agent.Victor Shihhttp://www.blogger.com/profile/03074915000996247481noreply@blogger.com2