The Junction's Journal
[Most Recent Entries]
[Calendar View]
[Friends]
Below are the 5 most recent journal entries recorded in
The Junction's InsaneJournal:
| Monday, December 7th, 2009 | | 2:07 pm |
next whenever http://www.ethelred.org/articles/2009/12/07/next-whenever/ http://www.ethelred.org/?p=264 It appears from a couple of confusing arrangements recently that Americans who say e.g. ‘next Friday’ mean ‘Friday next week’. Whereas I, being literal-minded, interpret it as ‘counting from today (which is Monday), the next Friday is Friday this week’.
In other time-related language, people here say ‘quarter of’, and I still can’t remember if that means ‘quarter past’ or ‘quarter to’. And if I say ‘half ten’ they don’t know if I mean 9:30 or 10:30 (it’s the latter).
| | Friday, June 19th, 2009 | | 10:39 am |
dns323 podcast and torrent downloader http://www.ethelred.org/articles/2009/06/19/dns323-podcast-and-torrent-downloader/ I’ve expanded on my previous podcast downloader program so that it gets torrents as well. I was running Automatic but it seemed silly to have two programs doing more or less the same thing.
I also didn’t like the configuration of Automatic, which has a global set of regexps it applies to all feeds to decide whether to download an item. My program has separate regexps for each feed which I think is a bit easier to deal with. In order to make the config file easy to parse, it is actually another Ruby file, which is read with instance_eval. By having methods defined as feed and matches the config file can just use those and look relatively sane:
feed 'http://some.feed.url/blah.rss'
matches 'title.to.match.*\d+'
(Some people would call this a DSL, but I think that’s stretching a point)
To make the torrents get into Transmission, the torrent downloader we’re using, I just call the transmission-remote command. Sometimes it’s easier to use what works.
So here’s the full program (see my previous post for how to set things up on the DNS-323):
#!/ffp/bin/env ruby
require 'open-uri'
require 'rss'
CONFFILE='/ffp/etc/mypodder2.conf'
PODCASTDIR='/mnt/HD_a2/podcasts'
TORRENTDIR='/mnt/HD_a2/torrents'
TORRENT_UPLOAD='/ffp/bin/transmission-remote "127.0.0.1:9091" -a "%s"'
class ConfigParser
def initialize(feeds)
@feeds = feeds
end
def parse(file)
instance_eval(File.read(file), file)
end
def feed(url)
@current = Feed.new(url)
@feeds << @current
end
def matches(pattern)
@current.add_pattern(pattern) if @current
end
alias :or :matches
end
class Feed
def initialize(url)
@url = url
@patterns = []
end
def uri
@url
end
def add_pattern(pattern)
if(pattern && pattern.length > 0)
@patterns << Regexp.new(pattern, true)
end
end
def allow?(item)
icompare = item.title
@patterns.empty? || @patterns.find {|p| p =~ icompare}
end
end
class Main
def initialize(options = {})
@options = {:config => CONFFILE, :verbose => false}.merge(options)
@feeds = []
read_config
end
def read_config
ConfigParser.new(@feeds).parse(@options[:config])
end
def vprintln(sometext)
if(@options[:verbose])
puts sometext
end
end
def torrent?(item)
item.enclosure.type =~ /.*torrent/
end
def run()
@feeds.each do |feed|
vprintln "checking feed #{feed.uri}"
rss_content = ""
open(feed.uri) do |f|
rss_content = f.read
end
rss = RSS::Parser.parse(rss_content, false)
rss.items.each do |item|
vprintln " + checking item #{item.title}"
if(item.enclosure && feed.allow?(item))
iurl = item.enclosure.url
vprintln " + + allowed item #{iurl}"
ctitle = rss.channel.title.gsub(/\W/, '_')
base = PODCASTDIR
base = TORRENTDIR if torrent?(item)
system("mkdir -p #{File.join(base, ctitle)}")
system("chmod a+rw #{File.join(base, ctitle)}")
ifile = File.join(base, ctitle, File.basename(iurl))
unless File.exists?(ifile)
puts "About to download #{iurl} as #{ifile}"
system("wget -O #{ifile} #{iurl}")
if(torrent?(item) && File.exists?(ifile))
system(sprintf(TORRENT_UPLOAD, ifile))
end
else
vprintln " + + file exists"
end
end
end
end
end
end
if __FILE__ == $0
require 'optparse'
options = {}
opts = OptionParser.new do |op|
op.on("-f CONFIG", "--config CONFIG", "Specify config file (default #{CONFFILE})") do |f|
options[:config] = f
end
op.on("-v", "--verbose", "Output messages") do
options[:verbose] = true
end
# No argument, shows at tail. This will print an options summary.
op.on_tail("-h", "--help", "Show this message") do
puts opts
exit
end
end
opts.parse(ARGV)
Main.new(options).run
end
| | Thursday, June 25th, 2009 | | 1:12 pm |
Comcast are scum http://www.ethelred.org/articles/2009/06/25/comcast-are-scum/ The ‘Digital Television Switchover’ took place here a couple of weeks ago. Not long after, we received this letter from Comcast[PDF 900kB]. While I suspect it doesn’t say anything that is actively illegal, I do think it could be highly misleading and is taking advantage of less well informed people.
Q: How do I get my signal back?
A: There are several options, but the easy answer is to call Comcast.
How do you quantify ‘easy’? Comcast’s offer probably is ‘easy’ in the sense that once you request their service, they’ll send an installer over to set everything up for you. Of course RCN, Verizon, DirecTV, Dish Network or others would do the same thing, so it pays to shop around, if that’s what you want. They’ll all need to you stay at home to wait for the installer, then add some extra boxes to the outside of your house, drill holes and run cable around.
Assuming you have a TV antenna in place, I think it’s quite easy to buy a digital converter box, connect the antenna to it, and connect it to the TV.
Q: How do I get FREE Basic Cable?
A: It’s easy… sign up for Internet and/or phone (each starting at just $24.95/mo.)
So this is that special kind of ‘free’ where actually you have to pay for something. Whichever deal you choose you’re out a minimum of $10 every month to Comcast, and reading the small print you may also have to pay for equipment, installation, taxes and other fees. Don’t forget, it’s only ‘free’ for the first year. Do you expect to watch TV for longer than a year?
Compare this to a digital converter box. You can request a converter box coupon which gives you $40 off the price. The boxes are selling for around $40 – $60, so your maximum outlay will be about $20 (plus sales tax), with no ongoing cost. If you were previously watching broadcast TV, you can use the same antenna.
Should you take up Comcast’s offer?
I don’t intend to. I don’t think it gains you anything other than another monthly bill. If you just want to get broadcast TV back, a converter box is a cheaper option. If you really want cable, look around at all the possibilities.
| | Thursday, August 13th, 2009 | | 1:20 pm |
Health Care Debate part 1 http://www.ethelred.org/articles/2009/08/13/health-care-debate-part-1/ I’ve been meaning to write comparing British and US health care for a while, but it’s not a very easy topic to get around. However it is the main subject in the news these days so it’s about time I weigh in.
The most emotive piece I’ve heard on the radio this week was from one of many ‘town hall’ meetings (I forget which). A sobbing woman says, “The president is trying to make us like Russia. I don’t want America to be Socialist!”
Of course, being me, this leaves me thinking, “but why?”. The speaker obviously thinks ‘Socialist’ is a ‘bad word’ – I don’t. (I’ll leave aside the debate over whether Russia is really socialist any more). Since the quote doesn’t give any more reasoning, I’m left to wonder what this woman is actually opposed to – she clearly feels strongly about it.
Unfortunately, to me, the opposite of socialism seems to be selfishness. Selfishness in health care seems to lead to a situation where you are fine while you remain healthy but if you are unlucky enough to get sick you’d better hope you can afford it. A lot of illness isn’t selfish, by the way – the flu is happy to spread fairly to all people, given the chance.
In practice paying for US health care is somewhere along the selfish/social scale. As companies or organisations buy group insurance plans, they form small pockets of socialness. The only reason insurance works is because it spreads the cost across a group of people, with the assumption that not everyone will suffer illness. So people who pay insurance premiums and are healthy, are necessarily subsidising the health care of people in the same group who are less healthy. That sounds like socialism to me.
Of course, the American argument is that people have freedom of choice about what insurance they buy, or don’t buy, and that the current debate is about the government taking away that freedom. I need to think more about that, so maybe more later.
| | Tuesday, November 24th, 2009 | | 1:57 pm |
bash twitter http://www.ethelred.org/articles/2009/11/24/bash-twitter/ http://www.ethelred.org/?p=259 There are probably lots of variants out there. In fact mine is largely copied from here Inspired by BLT
#!/bin/bash
# a twitter client (uses .netrc for auth)
confdir=~/.bt
seenfile=$confdir/seen
feedstyle=$confdir/btfeed.xsl
if [ "$1" == "-h" ]; then
echo " use: $(basename $0) -h | [ tweet ]"
echo " -h help"
echo " -i install"
echo " no arguments gets latest updates"
exit
fi
function binstall {
local sheet='<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:apply-templates select="//status"/>
</xsl:template>
<xsl:template match="status">
<xsl:value-of select="id"/><xsl:text>: <</xsl:text><xsl:value-of select="user/screen_name"/><xsl:text>> </xsl:text>
<xsl:value-of select="text"/><xsl:text>\n
</xsl:text>
</xsl:template>
</xsl:stylesheet>
'
if [ ! -d $confdir ]; then mkdir -p $confdir; fi
if [ ! -e $seenfile ]; then touch $seenfile; fi
if [ ! -e $feedstyle ]; then
echo -e $sheet > $feedstyle
fi
}
function friends {
local tnow=$( date --utc +%s )
local tthen=$( date --utc --reference=$seenfile +%s )
if [ $(( tnow - tthen < 60 )) = 1 ]; then
return
fi
local tmpfile=$( mktemp $confdir/result.XXXXXXXX )
curl --connect-timeout 5 -s -n $1 | xsltproc $feedstyle - > $tmpfile
local tmpu=$( mktemp ~/.bt/uniques.XXXXXXXX )
cat $seenfile $tmpfile | sort -n | uniq -u > $tmpu
cat $seenfile $tmpfile | sort -n | uniq > $seenfile
cat $tmpu $tmpfile | sort -n | uniq -d | cut -d':' -f2-
echo
rm $tmpfile $tmpu
touch $seenfile
}
function update {
curl -s -n -d "status=$msg" $1 &>/dev/null || echo "tweet broke"
}
if [ "$1" == "-i" ]; then
binstall
exit
fi
if [ -t 0 ]; then msg="$*"; else msg="$(cat -)"; fi
if [ "$msg" ];then
update http://twitter.com/statuses/update.xml
else
friends http://twitter.com/statuses/friends_timeline.xml
fi
Prerequisites
How to
1. Copy the above script into ~/bin/bt and make it executable.
2. Write a ~/.netrc containing something like this:
machine twitter.com
login exampleuser
password examplepassword
3. run bt -i to ‘install’. This will create a ~/.bt/ directory with a stylesheet and seen status file.
4. To check your friends timeline run bt with no arguments.
5. To post a message run bt <message> or pipe into bt. (Maybe for the next enhancement I’ll check the length of the message).
6. For friends updates while you use your bash command line, put something like this in your ~/.bashrc:
export PROMPT_COMMAND="bt; $PROMPT_COMMAND"
|
|