Nat's Dorking-it-Up Blog

Likely uninteresting for most people.

October 18, 2013

Kiev 2013 - Day 3

Went to the shooting range today. First up was the Glock 17 pistol. I've decided I do not like pistols and they don't like me. I was able to hit the target paper a few times at 25m but nowhere near the middle. Pass.

M-16 with a red dot site was much better. Five shots in the center (one in the very center) and the other five close by from 25m. Not much kick, very easy to shoot.

Next up, pump action single barrel shotgun. 10 for 10 on targets, but it's pretty hard to miss at what I'm guessing is 10 or 15m. Large diameter red circle sight makes it almost trivial to knock them down. Also not as much kick as I expected and very easy to handle.

Topping it off was (of course) the AK-47 with iron sites, this time at 50m. I discovered that I'm precise but not accurate whereas I was less precise but more accurate with the M-16. All my shots with the AK were clustered close together, but about 20cm to the right and up of the center.

Not sure if I have a favorite, I like all of them in different ways. The pistol being the most different in that I like it when it's not in my hands. Also I left my target papers in the car and will never see them again so I have no physical proof of any of this :-)

Ended the session with Ukrainian borscht and German beer. Now relaxing at the hotel until Yulia's parents arrive for the weekend. I anticipate more beer in the next few hours.

October 17, 2013

Kiev 2013 - Day 2

Much colder today. Walked Yulia to work across the street which involves quite a bit of walking - have to go a ways up the street to an underground crossing to get to the other side and then back down again. Met some co-workers and then back to the hotel to set up a shooting tour for tomorrow and run some errands to prepare for Yulia's family coming in tomorrow night.

Eventually made it downtown again and stumbled onto what I will call Little Paris - a street lined with abusively expensive French designer stores. I walked past them to a cafe for some perfectly cooked pelmeny and a beer :-)

Went up north this time to check out the river. Saw a huge metallic arch and a beautiful park stretching as far as I can see with contrasting dark trunk trees and bright yellow leaves. There is also a horrifying zip line 500+ meters across the entire river which I carefully avoided. Went instead for a long walk in the trees, eventually ending up at the soccer stadium. Interesting light structures there, especially with a backdrop of autumn trees. The ground was completely covered with yellow leaves, leaving lots of room for young couples to throw them at each other, kids to play and photographers and models to work. A very relaxing walk.

Took the metro back to the hotel this time having already walked quite a bit and dig in a bit to the remaining Breaking Bad episodes I haven't yet seen while waiting for Yulia. What a show. Dinner consisted of beer and sausages naturally, followed by a trip to the Bolshevik mall across the street. It features a prominent red and yellow logo of a marching soldier with a rifle on his back and a shopping bag in his hand. Lenin would be proud. Nonetheless, pants were secured to attend a show on Tuesday and also look respectable when Yulia's parents arrive tomorrow. Finished the night off with a nightcap at the hotel bar and cup of tea.

Looking forward to shooting tomorrow!

October 16, 2013

Kiev 2013 - Day 1

Arrived one day before Yulia, she's here on business but I'm just a tag along. Arrived late in the evening, had just enough time to hit the German restaurant in Hotel Cosmopolit and get a bratwurst and local brewed hefeweizen. Off to bed after a quick Skype with Yulia and Maxim.

Breakfast at the hotel is excellent, and they take their hot chocolate seriously here. Tiny cups of basically liquid chocolate, not the milky stuff like in the States. Tomatoes were fantastic (neat, they have flavor!). For some reason they only have still water and no sparkling - I thought I was in Ukraine but I guess not.

Some quick advice from the hotel staff got me on the metro and downtown in a hurry. Walked around all over the place, starting from Independence Square and then finding many churches and government buildings. Wound up accidentally in the theater district, then on to the university. They have quite an (old) arboretum there with some spectacularly tall trees inside, or at least that's how it appeared. Finished with a long walk for a couple km along a more industrial road which Google maps informed me would take me right back to the hotel (it did). Passed by the technical institute, which is fronted by a nice park with lots of trees. Leaves are all orange and yellow and starting to cover the ground, beautiful place. Passed the zoo, the ministry of infrastructure and a bunch of upscale interior design stores to arrive at our very out of the way hotel west of downtown. Lots of people along the way asked me for directions, so I take that to mean my "American look" is sufficiently hidden and as long as I keep my mouth shut all will be well.

Made it back to the hotel at about 3, tired of walking and very hot. It's about 13 degrees here, not cold enough for a sweater and jacket both. Time to kick back and write a blog entry, now off to find some food/beer, read, and wait to meet Yulia when she arrives.

February 13, 2011

ANTLR or Scala?

I like ANTLR and wanted to make a nice clean CSV grammar, as I didn't like the one on the ANTLR wiki (eats leading/trailing field white space, no good per RFC4180) and didn't see any others via Google. So I did, it's here.

As I was about to hack it up into something usable as a library I happened to be perusing some Scala docs and was reminded about Scala's built-in combinators. I gave it a shot even though there are others out there, though the existing docs/examples are pretty rough. I have to say after some effort it's pretty clean and far shorter than my ANTLR grammar at 23 lines (if you don't count the "parseCSV" convenience methods):
import scala.util.parsing.combinator.RegexParsers

trait CSVParser extends RegexParsers {

    import scala.util.parsing.input.CharSequenceReader
    import scala.util.parsing.input.StreamReader
    import java.io._

    override def skipWhitespace = false

    protected def records = repsep(record, """\r?\n|\r""".r)

    protected def record: Parser[List[String]] = repsep(field, ",".r)

    protected def field: Parser[String] = quoted_field | unquoted_field

    protected def quoted_field: Parser[String] = """"(""|[^"])*"""".r ^^ {
        s: String => s.substring(1, s.length()-1).replaceAll("\"\"", "\"")
    }

    protected def unquoted_field: Parser[String] = """[^,"\r\n]*""".r

    /**
     * Returns a list of CSV records, each a list of strings. If there were no records found or there was an error, None is returned
     */
    def parseCSV(reader: scala.util.parsing.input.Reader[Elem]): Option[List[List[String]]] = {
        parseAll(records, reader) match {
            case s: Success[List[List[String]]] => Some(s.result)
            case _ => None
        }
    }

    def parseCSV(input: CharSequence): Option[List[List[String]]] = parseCSV(new CharSequenceReader(input))

    def parseCSV(input: InputStream): Option[List[List[String]]] = parseCSV(StreamReader(new InputStreamReader(input)))

    def parseCSV(reader: Reader): Option[List[List[String]]] = parseCSV(StreamReader(reader))

    def parseCSV(file: File): Option[List[List[String]]] = {
        val fr = new java.io.FileReader(file)
        try {
            parseCSV(fr)
        } finally {
            fr.close
        }
    }

}
Even with convenience wrapper methods, coming in at 48 lines to get to something readily usable is pretty impressive. I really do like ANTLR, but at this point I can't justify the effort of hacking up my grammar to get to something usable (in java).

Scala 1, ANTLR 0.

April 16, 2009

Patch for Yaws 1.81 -- Hide your webserver identity

This is a patch for making attackers think you are running Windows and IIS/7.0, when in fact you are running *nix and Yaws. It also includes some mime types for XML/XSLT and .crt files.


diff -ur ./src/mime.types ../yaws-1.81/src/mime.types
--- ./src/mime.types 2009-04-16 12:02:43.000000000 -0700
+++ ../yaws-1.81/src/mime.types 2009-04-16 12:23:35.000000000 -0700
@@ -203,7 +203,7 @@
application/vnd.motorola.flexsuite.kmr
application/vnd.motorola.flexsuite.ttc
application/vnd.motorola.flexsuite.wem
-application/vnd.mozilla.xul+xml
+application/vnd.mozilla.xul+xml xul
application/vnd.ms-artgalry
application/vnd.ms-asf
application/vnd.ms-excel xls
@@ -331,9 +331,10 @@
application/x-ustar ustar
application/x-wais-source src
application/x400-bp
-application/xml
+application/xml xml xsl
application/xml-dtd
application/xml-external-parsed-entity
+application/xslt+xml xslt
application/zip zip
audio/32kadpcm
audio/basic au snd
@@ -465,7 +466,7 @@
text/vnd.wap.wml wml
text/vnd.wap.wmlscript wmls
text/x-setext etx
-text/xml xml xsl
+text/xml
text/xml-external-parsed-entity
video/mp4v-es
video/mpeg mpeg mpg mpe
@@ -490,3 +491,4 @@
application/xhtml+xml xhtml
image/svg+xml svg
application/ogg ogg
+application/x-x509-ca-cert crt pem
diff -ur ./src/yaws.erl ../yaws-1.81/src/yaws.erl
--- ./src/yaws.erl 2009-04-16 12:02:43.000000000 -0700
+++ ../yaws-1.81/src/yaws.erl 2009-04-16 12:47:42.000000000 -0700
@@ -577,13 +577,7 @@
end).


-address() ->
- ?F("
~s Server at ~s
",
- [
- (get(gc))#gconf.yaws,
- (get(sc))#sconf.servername]).
-
-
+address() -> "".

is_space($\s) ->
true;
@@ -699,7 +693,7 @@


printversion() ->
- io:format("Yaws ~s~n", [yaws_generated:version()]),
+ io:format("Microsoft-IIS/7.0~n"),
init:stop().

%% our default arg rewriteer does's of cource nothing
@@ -1284,13 +1278,7 @@
"\r\n"]
end.
make_server_header() ->
- HasDav = ?sc_has_dav(get(sc)),
- ["Server: Yaws/", yaws_generated:version(), " Yet Another Web Server\r\n" |
- if HasDav == true ->
- ["DAV: 1\r\n"];
- true ->
- []
- end].
+ ["Server: Microsoft-IIS/", "7.0", "\r\n"].

make_last_modified_header(FI) ->
N = element(2, now()),

March 28, 2009

plist to JSON (including your iTunes library...)

This is a quick-and-dirty sed script to convert a plist XML file to a no-unnecessary-whitespace JSON format. It has a few caveats, however:

  • It uses extended regular expressions

  • It slurps the entire XML text into memory before spitting it back out; it does not perform the traditional line-by-line editing/printing as most sed scripts do

  • <data> elements are given empty string values


Because of the above conditions, you have to use the "-En" options when running sed otherwise you will get garbage output (on Mac OS X, at least). Here is the code, I saved it in a file called "plist-to-json.sed" and invoke it as "sed -Enf plist-to-json.sed ...":

# Kill newlines
/^[[:space:]]*$/ d

# Kill leading whitespace
s|^[[:space:]]*||g

# Kill trailing whitespace
s|[[:space:]]*$||g

# Kill any base64 lines, <data> elements will not be converted
/^[[:alnum:]]+=*$/ d

# Kill the <?xml...?> line
s|<\?[^>]*>||g

# Kill any XML processing instructions
s|<![^>]*>||g

# String escape any values for JSON
s|"|\\"|g

# Convert the top level <plist> element to an object with a "plist" field
s|<plist[^>]*>|{"plist":|
s|</plist>|}|

# Keys, strings and dates get surrounded with quotes, numbers and booleans left alone
s|<key>|"|g
s|</key>|":|g
s|<string>|"|g
s|</string>|",|g
s|<real>||g
s|</real>|,|g
s|<integer>||g
s|</integer>|,|g
s|<true[[:space:]]*/>|true,|g
s|<false[[:space:]]*/>|false,|g
s|<date>|"|g
s|</date>|",|g

# Arrays and dictionaries convert nicely
s|<array>|[|g
s|</array>|],|g
s|<dict>|{|g
s|</dict>|},|g

# Give <data> elements an empty value
s|<data>|""|g
s|</data>|,|g

# Append the pattern space into the hold space
H

# Everything here happens only on the last line of input, after the above stuff has run
${
# Bring the hold space into the pattern space (the entire document)
g

# Remove tailing commas from the last field definitions in a JSON object
s|,[[:space:]]*}|}|g
s|,[[:space:]]*]|]|g

# Kill remaining unnecessary whitespace
s|:[[:space:]]*|:|g
s|{[[:space:]]*|{|g
s|\[[[:space:]]*|[|g
s|\n||g

# Print out the resulting JSON
p
}


Using this I was able to take my "iTunes Music Library.xml" file (2,365,981 bytes) and convert it nicely to JSON (1,087,270 bytes), which I intend to use in a Flash/Flex application I want to build to listen to my iTunes music over the internet. Unfortunately, Mediamaster (a company I used to work for) is not going to exist anymore and I miss the service... this will be my pathetic attempt at a replacement as I have absolutely no UI skills at all.

September 25, 2008

Simple Revision Control

Many people (including some of my family members) do not use revision control or even know what it is. They have lots of files with funny extensions on their computers (doc1.doc, doc2.doc, doc3.doc) that are different versions of the same document. Sometimes there will be many folders or a combination of files and folders; all in the name of being able to go back in time to see what something used to look like, so that information is permanently lost when you overwrite it.

I think that's terrible and I'm trying to convince my family members to use revision control since it solves this problem nicely, thus the reason for this post. It it very simplified, but should be more than adequate for most computer users to help keep track of changes to their files.



Download and install this: http://tortoisesvn.net/downloads. It is a Windows "extension" -- meaning when you right-click on files and folders you will have a new menu to choose from after you reboot after installation. The program is called "TortoiseSVN" -- it's free and (I think) very usable and convenient.

Here are the basics of revision control:
  1. Everything you want to keep track of is centrally stored in a repository
  2. When you want to make changes to something in a repository, you do a check-out into a folder on your computer
  3. The folder that you checked out in step 2 is called a working copy
  4. When you make changes and want to save them, you commit your changes to the repository, when you do so you provide a comment stating what your change was. This comment is recorded in the log for that file or directory.
  5. You can browse a repository, and for any file or folder inside it you can see its full history of commits (changes), as well as each log message.
  6. In addition to seeing a full history of changes, you can also see the contents of a file/directory at any point in time, so if you decide you don't like a change or need to find something you wrote a long time ago, you can find it.
This tool "TortoiseSVN" enhances the regular Windows Explorer to give you the functionality, using the "Subversion" software ("SVN" for short). It's what many companies and independent projects use to track changes to their work. And while organizations and groups have advanced usage of it, what I described here can be used by anyone with a computer who makes changes to their files over time; spreadsheets, documents, pictures, financial files... anything you might change over time.

To set it up:
  1. Create a repository. Make a new folder somewhere (perhaps C:\repo or something obvious), right-click on it and from the TortoiseSVN menu choose "Create repository here"
  2. Create a working copy. Go make a new directory under "My Documents" (or someplace else you will remember) -- this is a directory where you will be loading/saving your documents from. Right-click on it and choose "SVN Checkout," then for the "URL of repository" put in "file:///C:/repo", then choose "Ok". If you chose something other than "C:\repo", just put "file:///C:/" to start with, then browse to it using the box to the right.
  3. Collect your files you want to keep track of. If you have them, copy your existing documents into your working copy folder. You can put anything you want in there including files, folders (and sub-folders), whatever.
  4. Add your existing files to SVN. SVN wants to be told explicitly what to worry about and what not to, so if you see icons with a question mark by them (as you now should), you can right click on them and choose "Add" from the menu. The icons should change to plus signs at that point -- they are poised to be controled by SVN now.
  5. Commit your new files/folders. Once you have placed your existing documents in your working copy, right-click on the working copy folder and choose "SVN Commit..." from the menu. Enter a comment and hit "Ok" -- you just made your first revision!
To use it day to day:
  1. Stay up to date. At any time you can right-click on your working copy and choose "SVN Update" from the menu to make sure everything is in order.
  2. Edit your files. Make whatever changes you want to your files, add new files or folders, etc. Make sure when you are done that you explicitly add new files -- they will have a question mark icon next to them so they should be easy to identify.
  3. Commit your changes. When you reach what you think is a good point in time to save your work, commit your changes like you did above. Perhaps you added an important idea (even if it isn't finished yet), updated your address book with a new contact, updated your resume, whatever makes sense for you.
  4. Go to step 1.
That's it! At any point you can right-click on your working copy, choose "Show log" from the TortoiseSVN menu, and instantly see a complete trail of all your commits including what files were changed/modified/removed, when you did it, and what comment you wrote when you committed each change.

Hopefully that is enough to get everyone going, and hopefully it is intuitive enough from this point how to use TortoiseSVN to do what you want. If you need more information please leave a comment here, or you can see the TortoiseSVN website at http://tortoisesvn.net/ or the Subversion book online at http://svnbook.red-bean.com/en/1.5/index.html.