Joining two sets with LINQ

Dealing with a horrible database this last week, I found the need to combine things in a reasonable way. It took a lot of searching to find out how to query on multiple sets. So thought I would put it here.

var roles = (from x in userRoles
                from y in editUser.UserRoles
                where y.SOXRole && y.Id == x.RoleId
                select x).ToList<DBModel.UserToRoles>();

I was pretty happy with it.

c# linq

Posted on

The Sky is not falling

Here is an article that explains in clear simple terms why the CIA Vault7 leaks are not the end of the world. If you consider yourself technical (which you do, you are reading a blog after all) you really have to help constrain the insanity in the face of leaks.

Just because you can read 'breaking signal by attacking the device' it does not mean that signal is broken. You have a responsibility to your friends and family, if they panic when they read the news and fall back to SMS because whatsapp is broken , the world is not becoming a better place.

Read what trusted security people say, validate their comments, help your family.


Reading: Gun Machine, The Difference Engine

Presentations with remarkjs

I enjoyed using mdp to write slides, being able to hammer in markdown gave a satisfying sense of flow and I felt like I was able to get the slides out of my head in a straightforward manner. But I knew for my eurobsdcon presentation I was going to have to include photos of equipment and maybe even demo videos.

Shelling out to vlc or feh for pictures and video wouldn't do, it would throw off both me and the audience. That ruled out using mdp for making slides and it also ruled out using sent from suckless

I canvassed around on mastodon and tried out a bunch of other tools, the main factor in ruling out most of the tools was there handling of very long titles. Something I couldn't avoid when the title of my talk was 84 charactars.

remarkjs was the tool I settled on.

remarkjs can take slides either as an external markdown file if you have a way to serve them to the js, or embedded into a html file. I ended up embedded the slides into the markdown as this was the fastest way to get from nothing to having some slides appearing. remarkjs has a boat of documentation, which I thourghouly ignored until after the presentation, in fact in the days after when I was toying with implementing a presentation view I found remarkjs already has one built in!

remarkjs was great for authoring into, the ability to add style to documents was a big bonus for me too. The fact there was style did mean I had to write some css to get videos into the right place in the slide was annoying, but it worked out well.

Integrating diagrams

My mdp slides included diagrams as most slide decks do, I wanted to add diagrams to this slide deck. The mdp diagrams are just ASCII art, showing ASCII art in a web page is fine, that is show I made a sharable version of the page, but I felt I could do better.

goat can render ascii art diagrams in a restricted set into svg diagrams.

example example example

Gives an svg diagram like:

svg

The svg output is very verbode and really not something you would want to embed in the middle of a slide deck.

svg quoted cut off

For this to be managable I wrote a python script to 'render' the document. The script searches the input for lines starting with 'diagram:' and takes the remainder of the line as a file name to render and substitute.

import sys
import subprocess

filename = sys.argv[1]
infile = open(filename, 'r')
outfile = open('out.html', 'w')

cmd = "cat"
cmd = "goat"

for l in infile:
    if l.startswith('diagram:'):
        if len(l.split(' ')) != 2:
            print('bad line {}'.format(l))
        diagram = 'diagrams/{}'.format(l.split(' ')[1].strip())

        result = subprocess.run([cmd, diagram], stdout=subprocess.PIPE, encoding='utf-8')
        if result.returncode == 0:
            count = 0
            outfile.write('.center[\n')
            for o in result.stdout.split('\n'):
            #    print('    ' + o)
                outfile.write(o + '\n')
            outfile.write(']\n')
        else:
            for o in result.stdout:
                print(o, end='')
            outfile.write(l)
    else:
        outfile.write(l)

infile.close()
outfile.close()

I really like remarkjs

I was happy enough using remarkjs that I was considering adding a presentation mode. However there are some downsides, firefox really struggled when rendering slides, when I had 40MB mp4 video files firefox would peg all cpus, as the slides were just a page the autoplaying video pulled firefox down all the time.

remarkjs "supports" exporting to pdf via chromes print preview, but all I could get chrome to do was hang. Someone else managed to get an export from safari, overall not the best.

Presentations with mdp

It feels like work is just a constant stream of preparing, travelling for and giving presentations. Brief words and pictures is an excellent for conveying information between small groups of humans. All of these presentations I write in keynote , keynote manages to be light weight, powerful and not horrific to use. As a bonus, my boss feels at home in keynote and is happy to make edits there.

The keynote workflow does not match well to how I think. When dreaming up a presentation I want to shit of a stream of conciousness and have it magically become slides in the right shape.

I might write a series of headings like:

# intro
# who
# meat 
# details
# questions?

I will iterate on these to add bodies, details and more slides.

For quite a while I have wanted a system where I could write plain text and have it become slides. I wrote about the sent tool from suckless, but in the end I found it wanting. I have also considered just showing screens of text, but a nightmare DEFCON wireess village talk by Hak5 scared me away. They attempted to just present using just a plain text file and less, but the window size got out of whack and it all fell apart.

Enter mdp

mdp is a terminal presentation program, it takes slides it approximately markdown and takes over the entire terminal as its presentation surface.

Intrigued I used an opportunity to speak at a local tech event to try out mdp . The slides from that presentation can be found on my talks page and overall I thought mdp worked quite well.

I was able to draft in the stream of conciousness style I want, getting the bulk of the slides written very quickly. Adding diagrams required resorting to ASCII art which isn't so bad, I like ascii art . mdp worked great in practice, I had to find readable dimensions for the text by trial and error, but overall it went well.

Plain text as a format does have some major downsides, mdp has a way to encode builds for text (see below), but I couldn't use it with my tools. ASCII art diagrams also meant that the builds I did use were eggregious to maintain, any modification required manual propigation through the build chain.

mdp does not support a portable output format. You may say the source markdown is an excellent format for portability, but I find it lacks the crispness of having a single slide in view at once.

I wanted to be able to point at a viewable copy of my slides and so I hacked together some tools to export the mdp presentation to html, but for this I had to sacrifice the built in build mechanism of mdp

Finally there was no way to include images in the mdp presentation let alone the sacride gif format required to correctly convey nyan cat. I played with some terminal graphics viewers, but none of them worked well and after a while I started to think 'what is the point of reinventing everything'.

Drafting the presentation in markdown fit very well with my work flow, but the difficulties in getting a complete presentation with mdp meant that I didn't want to use it for future presentations.

Exporting to html

Getting html of the mdp presentation hinged on a complete hack. There is a tool I had seen in the past that can output a html dump of a tmux session unsurprisingly called tmux2html . With some playing around I was able to automate a tmux session to work through the slides and use tmux2html to grab each slide as a frame.

Finding the number of slides in the deck required splitting on the slide seperator from the markdown, this ruled out using the built in build mechanism as I would end up with the wrong number of slides.

The output script runs through the markdown to find the number of slides then uses tmux send-keys to control moving through the deck.

#!/bin/sh

set -e 

command -v tmux >/dev/null 2>&1 || { echo >&2 "I require tmux but it's not installed.  Aborting."; exit 1; }
command -v tmux2html >/dev/null 2>&1 || { echo >&2 "I require tmux2html but it's not installed.  Aborting."; exit 1; }
command -v mdp >/dev/null 2>&1 || { echo >&2 "I require mdp but it's not installed.  Aborting."; exit 1; }

if [ -z "$1" ]
  then
    echo "tohtml presentatin.md [outfile.html]"
    exit
fi

file=$1
outfile=outfile.html

if [ ! -z "$2" ]
  then
  outfile=$2
fi

javascript="<script>function page(){var e=!1,n=document.getElementsByClassName('tmux-html'),l=0; document.onkeydown=function(t){if(t=t||window.event,key=t.keyCode,e)if(13==key){e=!1,l=0;for(var i=0;i<n.length;i++)n[i].style.display='inline'}else{37==key&&--l<0&&(l=0),39==key&&++l>=n.length&&(l=n.length-1);for(i=0;i<n.length;i++)n[i].style.display='none';n[l].style.display='inline'}else if(13==key){e=!0,n[0].style.display='inline',l=0;for(i=1;i<n.length;i++)n[i].style.display='none'}}}window.onload=function(){page()};</script>"

tmpfile=tmpfilenamefilething
tmux='mdptohtmlconverstionsession'

slides=`grep -e "^---" $file | wc -l`

tmux new-session -s $tmux -d -x 96 -y 25

tmux send-keys -t $tmux "mdp $file"
tmux send-keys -t $tmux "Enter"

tmux send-keys -t $tmux 'g'
tmux2html -o $tmpfile $tmux 1>/dev/null

# insert javascript
lines=`cat $tmpfile | wc -l`
styleend=`cat -n $tmpfile | grep -e "</style>" | awk '{print \$1}'`
head -n $styleend $tmpfile > $outfile
echo $javascript >> $outfile
tail -n $((lines-styleend)) $tmpfile >> $outfile
mv $outfile $tmpfile

# remove closing tag
lines=`cat $tmpfile | wc -l `
end=`tail -n 1 $tmpfile`
head -n $((lines-1)) $tmpfile > $outfile

echo turning $file into $((slides+1)) slides 

i=1
while [ $i -lt $((slides+1)) ]
do
    printf "\rSlide $i"
    tmux send-keys -t $tmux 'j'

    tmux2html -o $tmpfile $tmux 1>/dev/null 
    grep -e "^<div" $tmpfile >> $outfile
    (( i++ ))
done

echo $end >> $outfile
tmux kill-session -t $tmux 
rm $tmpfile
printf "\rwritten to $outfile \n"

If you view the presentation page you will see the entire slide deck, this was the first output I got from this script. All the slides in a nice order. After a little pondering I wrote up some javascript to give controls, if you hit enter it will go from all slides to single slide. Arrow keys in single slide mode will allow you to move through the slide deck. The unminified javascript for this is below.

function page() 
{
    var presenting = false
    var elements = document.getElementsByClassName('tmux-html');
    var current = 0;

    document.onkeydown = function(evt) {
        evt = evt || window.event;
        key = evt.keyCode 

        if (presenting) {
            if (key == 13) {
                presenting = false;
                current = 0;
                for (var i = 0; i < elements.length;i++)
                    elements[i].style.display='inline'
            } else {
                if (key == 37) {    //left
                    current--;
                    if (current < 0)
                        current = 0;
                }
                if (key == 39) {    //right
                    current++;
                    if (current >= elements.length)
                        current = elements.length-1;
                }
                for (var i = 0; i < elements.length;i++)
                    elements[i].style.display='none'
                elements[current].style.display='inline'
            }
        } else {
            if (key == 13) {
                presenting = true;
                elements[0].style.display='inline'

                current = 0;
                for (var i = 1; i < elements.length;i++)
                    elements[i].style.display='none'
            }
        }
    };
}

window.onload = function () {
   page();
}