Using Matrix to connect to Slack from an IRC client on Ubuntu

Andy Balaam from Andy Balaam's Blog

I like using HexChat to talk to my colleagues, like one other guy. It is fast, and it pops up a new window when someone sends me a direct/private message.

Recently, Slack shut down their IRC gateway, forcing me to use their slow UI, and making me unable to be responsive to direct messages without spending my entire life checking said UI, or being disturbed by notifications.

So, I decided to set up a Matrix bridge, because how hard can it be?

My system is Ubuntu MATE 18.04.

What I did

Install Synapse

Install Synapse, a Matrix homeserver.

wget -qO - https://matrix.org/packages/debian/repo-key.asc | sudo apt-key add -
sudo apt-add-repository http://matrix.org/packages/debian/
sudo apt update
sudo apt install matrix-synapse

Edit /etc/matrix-synapse/homeserver.yaml to change the line containing “registration_shared_secret” to look something like:

registration_shared_secret: "some secret password you made up"

(Replacing “some secret password you made up” with something secret.)

Make a new user:

register_new_matrix_user -c /etc/matrix-synapse/homeserver.yaml http://localhost:8008

Enter a username and password, and take a note of them.

Install Riot

(Technically, this step is optional, but I definitely recommend it to check everything is working.)

Install Riot, a client that can talk to a homeserver.

curl https://riot.im/packages/debian/repo-key.asc | sudo apt-key add -
sudo apt-add-repository https://riot.im/packages/debian/
sudo apt update
sudo apt install riot-web

Start Riot from the menu or by typing riot-web in a console.

Choose to log in to a Custom Server (not create a new user), and enter the Home Server URL as http://localhost:8008, leave the Identity Server URL as it is, and enter the username and password you entered in the previous step.

Riot should be able to connect to the Synapse server, even though it won’t have any rooms in it yet.

If this doesn’t work, try running riot-web in a console, and check the Synapse log file at /var/log/matrix-synapse/homeserver.log

Install matrix-puppet-slack

(Note: after this step, the homeserver can only be for you now, because it is logged into Slack as you. If you want to make a new Matrix server for lots of people, I found that matrix-appservice-slack works, but this only connects channels, not direct messages.)

Get a Slack legacy token which matrix-puppet-slack will use to connect to Slack as you. Follow the instructions given at that link, and you should end up with a token that looks something like “abcd-123456768-ETC-ETC”. Keep a note of it.

Install matrix-puppet-slack which allows you to connect a homeserver to a Slack instance, pretending it is you:

cd
git clone https://github.com/matrix-hacks/matrix-puppet-slack.git
cd matrix-puppet-slack/
npm install
cp config.sample.json config.json

Edit config.json so it looks something like this:

{
  "slack": [{
    "team_name": "Name of my team",
    "user_access_token": "abcd-123456768-ETC-ETC"
  }],
  "registrationPath": "slack-registration.yaml",
  "port": 8090,
  "bridge": {
    "homeserverUrl":"http://localhost:8008",
    "domain": "localhost",
    "registration": "slack-registration.yaml"
  }
}

Now generate a config file that Synapse will use, called slack-registration.yaml, by typing this command (still in the matrix-puppet-slack directory):

node index.js -r -u "http://localhost:8090"

When asked, type in the username and password you entered in the first step (when you ran the register_new_matrix_user command).

This creates a config file telling Synapse that matrix-puppet-slack is running on the local machine on port 8090.

Now, run it:

node index.js

and edit Synapse’s config file /etc/matrix-synapse/homeserver.yaml to point at the new config file you just made, by editing the line mentioning app_service_config_files so that it looks like this:

app_service_config_files: [
    "/path/to/matrix-puppet-slack/slack-registration.yaml"
]

Make sure you replace “/path/to/matrix-puppet-slack” in the above with the directory where you put matrix-puppet-slack, which is /home/yourusername/matrix-puppet-slack if you followed the instructions exactly.

Restart Synapse, and when you go back into Riot, you should see your Slack channels appear gradually (as people talk in them):

sudo service matrix-synapse restart

If not, check the output from the node index.js command, and the Synapse log file at /var/log/matrix-synapse/homeserver.log.

Install matrix-ircd

To allow connecting to Matrix from an IRC client, install matrix-ircd:

cd
git clone https://github.com/matrix-org/matrix-ircd.git
cd matrix-ircd
cargo build
cargo run -- --url "http://localhost:8008"

(Note this works on Ubuntu 18.04, but operating systems with older versions of Rust may need to get the latest first – see the matrix-ircd page for details.)

Connect from an IRC client

Now use an IRC client to connect to matrix-ird. I recommend HexChat if you’re looking for one.

matrix-ircd runs on port 5999 by default, so you should be able to connect to it from your IRC client by setting the server to localhost/5999 and using the username and password from the first step (when you ran the register_new_matrix_user command). Use plain username/password authentication.

If it works, you should see your Slack channels appear in your IRC client. If not check the logs mentioned before, and the error messages and logs from your IRC client.

What works and doesn’t work

  • Messages typed by me and others into IRC, Riot and Slack appear in all the other places, including direct messages.
  • Synapse and Riot are installed fully, so Synapse will be running after a reboot, and Riot is available in the menus, but matrix-puppet-slack and matrix-ircd are just running in a console, and have to be manually started. It should be reasonably simple to make custom systemd files to start them automatically.
  • matrix-puppet-slack crashed once and I had to restart it, so this may not be very reliable.
  • The Slack channel names look terrible in my IRC client. I think matrix-ircd needs to find the pretty names (which are displayed correctly in Riot) and use them instead of the coded names used under the cover in Matrix.
  • My first ever direct message to someone does not work, even though I can choose them and attempt to send a message. As soon as they say something to me, they appear as a channel in Riot and IRC, and I can talk back and forth no problem from then on.
  • Direct messages look like normal channels in Matrix, which means I can’t use HexChat to pop up notifications for them, so this was all pointless.

Please leave comments below if you know how I can fix any of these problems.

Conclusions

  • Matrix seems really cool
  • It is basically possible to bridge IRC-Matrix-Slack as I wanted
  • But, some remaining bugs mean I have to keep using Slack’s UI for now :-(
  • Please comment telling me how to do this better

Function Template Partial Ordering: Worked Examples

Simon Brand from Simon Brand

C++ function overloading rules are complex. C++ template rules are complex. Put the two together, and you unfortunately do not get something simple; you get a hideous monster of standardese which requires great patience and knowledge to overcome. However, since C++ is mostly corner-cases, it can pay to understand how the rules apply for those times where you just can’t work out why your code won’t compile. This post will present a few step-by-step examples of how partial ordering of function templates works in order to arm you for these times of need.

Partial ordering of function templates is a step of overload resolution. It occurs when you call a function template which is overloaded and the compiler needs to decide which one is more specialized than the other. Consider this code:

template<class T> void f(T);        //(1)
template<class T> void f(T const*); //(2)

int const* p = nullptr;
f(p);

We expect f(p) to call (2), because p is a int const*. In order to decide that (2) is more specialized than (1), the compiler needs to follow the function template partial ordering rules. Let’s see what the standard has to say.

Partial ordering selects which of two function templates is more specialized than the other by transforming each template in turn (see next paragraph) and performing template argument deduction using the function type.

This is not so complicated, even if the terms may be unfamiliar. Unfortunately, the “next paragraph” and the sections which it references are almost impossible to parse without a lot of background knowledge and re-readings, so I shall step through the algorithm rather than pasting the rules for you to cry over.

There are four steps which we to have work through:

  1. Transforming (1).
  2. Performing deduction on (2) with the transformed template from step 1.
  3. Transforming (2).
  4. Performing deduction on (1) with the transformed template from step 3.

If one and only one of the deductions succeeds, then the template with which the deduction was performed is more specialized than the other.

Step 1: The rules state that for each template parameter, we create some unique type to use in its stead1. Let’s call this unique type type_0. You can pretend that this was defined somewhere like class type_0{};. Now we take our function template template <class T> void f(T) and substitute in type_0 for T. This gives us void f(type_0). The transformation is complete.

Step 2: Now that we have transformed template <class T> void f(T) into void f(type_0), we will perform deduction on (2) using the transformed function type. To do this, we imagine a call to (2) where the arguments have the type of the parameters for (1). Concretely, it would look like this:

template <class T> void func_2(T const*);
func_2(type_0{}); //derived from void f(type_0)

Would this call succeed? We can put it into our compiler to find out. GCC 8.1 says:

<source>: In function 'int main()':
<source>:4:18: error: no matching function for call to 'func_2(type_0)'
   func_2(type_0{});
                  ^
<source>:1:25: note: candidate: 'template<class T> void func_2(const T*)'
 template <class T> void func_2(T const*);
                         ^~~~~~
<source>:1:25: note:   template argument deduction/substitution failed:
<source>:4:18: note:   mismatched types 'const T*' and 'type_0'
   func_2(type_0{});
                  ^   

So deduction from (1) to (2) fails, because the invented type type_0 cannot be used to deduce const T*.

Step 3: Let’s try from (2) to (1). Again, we’ll transform (2) from template <class T> void f(T const*) to void f(type_0 const*).

Step 4: Now we attempt deduction:

template <class T> void func_1(T);
type_0 const* arg = nullptr;
func_1(arg);

This succeeds because a type_0 const* can be used to deduce T. Since deduction from (1) to (2) fails, but deduction from (2) to (1) succeeds, (2) is more specialized than (1) and will be chosen by overload resolution.


Let’s try a different example. How about:

template<class T> void g(T);  //(1)
template<class T> void g(T&); //(2)
int i = 0;
g(i);

(1) transforms to void g(type_0). Before we try deduction, we need to apply one of the numerous additional rules from the standard, which says we need to replace references with the type being referred to. So template <class T> void g(T&) becomes template <class T> void g(T). Deduction time:

template<class T> void func_2(T);
func_2(type_0{});

This succeeds.

Now the other direction. template<class T> void g(T&) transforms to void g(type_0&), then we remove the reference to get void g(type_0). Our second deduction:

template<class T> void func_1(T);
func_1(type_0{});

This is effectively identical to the previous one, so of course it succeeds.

Since deduction succeeded in both directions, the call is ambiguous. Sure enough, GCC diagnoses:

<source>: In function 'int main()':
<source>:5:8: error: call of overloaded 'g(int&)' is ambiguous
     g(i);
        ^
<source>:1:24: note: candidate: 'void g(T) [with T = int]'
 template<class T> void g(T);  //(1)
                        ^
<source>:2:24: note: candidate: 'void g(T&) [with T = int]'
 template<class T> void g(T&); //(2)
                        ^ 

This is why the algorithm is a partial ordering: sometimes two function templates are not ordered.


I’ll give one more example. This one has multiple parameters and is a bit more subtle.

template<class T>struct identity { using type = T; };
template<class T>struct A{};

template<class T, class U> void h(typename identity<T>::type, U); //(1)
template<class T, class U> void h(T, A<U>);                       //(2)
h<int>(0,A<void>{});

identity here just evaluates to its template argument, but the important thing to note is that typename identity<T>::type is a non-deduced context, so T cannot be deduced from the argument for that parameter.

(1) transforms to void h(typename identity<type_0>::type, type_0), which is void h(type_0, type_0). Attempt deduction on (2):

template<class T, class U> void func_2(T, A<U>);
func_2(type_0{}, type_0{});

This fails because we can’t match type_0 against A<U>.

(2) transforms to void h(type_0, A<type_1>). Try deduction against (1):

template<class T, class U> void func_1(typename identity<T>::type, U);
func_1(type_0{}, A<type_1>{});

This fails because typename identity<T>::type is a non-deduced context, so we can’t deduce T.

In the example from the last section deduction succeeded both ways so the call was ambiguous. In this example, deduction fails both ways, which is also an ambiguous call.


That’s the last of the examples. Of course, there are a bunch of rules which I didn’t cover here, like Concepts, parameter packs, non-type/template template parameters, and cases where both the argument and parameter types are references. Hopefully you now have enough of an intuition that you can understand what the standard says when you inevitably hit those corner cases. If you have any partial ordering conundrums, drop them down in the comments below or send them to me on Twitter.


  1. I’ll ignore non-type template parameters and template template parameters for simplicity, but the rules are essentially the same. 

Because your “competitors have it” IS NOT STRATEGY

Allan Kelly from Allan Kelly Associates

iStock-514378725medium-2018-06-5-17-04.jpg

“We need a product that does X because our competitors have a product that does X”
“Our product needs feature Y because our competitors product has feature Y.”

It makes me want to cry.

Let me clear: building something because your competitors have it IS NOT A STRATEGY.

Neither is it a particularly good tactic.

Stop obsessing about your competitors and think about your customers.

I don’t doubt that your people are being told that customers are buying the competitor product because it has X or Y and I don’t doubt that some of your people feel that if you only matched the competitors feature for feature you would win but I just can’t see it myself.

For a start, is feature Y really the only thing loosing the sale? Are the products so well balanced that this one small thing is it? And is there really nothing that your product does better?

Try this simple experiment: tell the customer that feature Y will be delivered next month and see if they decide to buy yours there and then or find something else that makes the competition better.

Now lets suppose you decide to build Y. Before you make any plans ask yourself:

While you are building feature Y what are your competitors going to be doing?
Will they stand still or will they be adding feature Z?
And once they have feature Z will you need to play catch up?

Chances are that tomorrow you get to where you want to be (where your competitors are today) only to find your competitors have something else you don’t have either.

I’ll agree this is a good strategy if you have deliberately chosen to be a Fast Follower – you can play Android to your competitors iOS. Just make sure you know why your customers will choose your Android over the competitor iOS.

Will you be cheaper?
Or better?
Or will you bundle some other goodies with it?

Before you run to where your competitors are today ask yourself: where will your competitors be tomorrow?

If you still insist on building this feature you need to

  • Make sure you do a much better job (easier to use, more intuitive, faster to produce results, better quality results, or some such)
  • OR you need to do it fast and cheap so you can spend your precious resources on building something the competitor doesn’t have
  • OR you being overwhelming resources to the table so you are going to stand a chance. Every day you delay the competitor gets further ahead, so don’t try half measures

A better approach is to find out what your customers actually need. Stop looking at the features, go back to first principles: what is the problem your customers face? what is the job they are attempting to make progress with?

How can you help your customers with this job?
How can you make them faster?
How can you help them achieve their work more cheaply? Or at better quality? – in fact, what do “better” and “quality” look like to them.

Someone – I honestly forget who – told me earlier this year that they wanted to catch-up with their competitor and overtake them.

One small flaw there: if you build features to match your competitors you can never overtake them because you won’t know what to build once you reach parity.

Put it another way, you add all the features they have today, and all the features they add while you are catching up. What do you build next? Until they build their next version (and recapture the lead) you don’t know what to build. And if you build something different you just lost feature parity.

So, go back and examine what your customers are using your tool for. Look at the job to be done, look at how your customers are doing their job and using your tool and work out for yourself how you can help customers do a better job.

Celebrate the difference, explain why you are better.

And please forget about matching the competition.

I’m old enough to remember the days when WordStar was fighting WordPerfect, AmiPro was fighting them both, and all were better than Microsoft Word. Adverts and magazine reviews would compare them feature to feature. Someone somewhere thought people bought word processors based on the number of features.

Then Microsoft launched Windows and everybody went over to Microsoft Word for Windows almost overnight.

Don’t focus on your competitors. Focus on your customers. Unfortunately that requires more work and some original thinking.

The post Because your “competitors have it” IS NOT STRATEGY appeared first on Allan Kelly Associates.

Shooting with Flash (And Motofest 2018)

Samathy from Stories by Samathy on Medium

Talking about shooting with an on-camera flash at Coventry Motofest 2018.

I’ve never really used my flashgun before, mostly because on the odd occasion that I have used it at a shoot I ended up with under, or over exposed images and thus never wanted to risk wasting time and shots just to practice.

Last Saturday I decided to seriously try out my flash at an event where my photos were purely for myself, rather than with the intent to sell them.
I was shocked to find my results to be fantastic!

“The prettiest girl is riding in the ‘Stang!”

The day was probably quite appropriate for shooting with an on camera flash.
It was a little overcast and although bright-ish, things just were not popping very much.
So adding some light from a flash worked well.

The subjects seemed to work for flash too, shiny cars!

A row of MGs

I found that to get the exposure right I had to dial up the shutter speed or aperture so my camera was showing a couple 0.1 stops over exposure, otherwise the image would look too dark. Despite using i-TTL mode.
I wonder if this is because of using a diffuser and angling the flash at about 60 degrees, some of the light would be directed upwards and not hit the subject.

Using the flash without a diffuser was terrible, all images just had hugely over-exposed sections where the flash hit.
The regular hard-plastic diffuser that came with my flash is ‘fine’ — but the new one is certainly better. It results in a softer light that is much more directed towards the subject than the plastic one.
Instead, I used a diffuser I’d got from Amazon a few days before.

Flash comparison — Both same shutter, aperture and ISO. The left is lit with the new diffuser, the right with the hard plastic one.

From the above comparison it is clear to see that the new diffuser provides more light more widely spread across the image.

Example of a portrait photo where the flash is being bounced towards the subject well by rotating the diffuser.

The added benefit of this item is that it has a reflector in the back on the inside — allowing me to easily shoot portrait with on-camera flash and just rotate the diffuser so that light is still being bounced toward the subject from the front. Rather than the light ended up hitting the left or right side of the subject.

Below are a bunch of my favourite images from the event. But I got about 100 good ones.

It was a lot of fun being able to try out new equipment without the pressure of having to produce good images.

I now feel confident to get good photos with an on-camera flash.

Shooting different subject for once was also fun! When shooting static subjects one has a lot more time to choose the composition of an image. Although I note now that most of my images see the subject square in the centre of the frame.

60% of the time, works every time
Whatever level of zip ties you’re on, you’re not on this level of zip ties.
Lego block engine cover in a Nissan Cube
An Aston Martin V8 Vantage in Gulf livery
More Gulf livery, this time on a VW Golf.
Jacuar
I also got to try out my 100mm macro lens — although it is certainly too long a focal length for shooting cars.
Ford V8 with Holley carburettor.
I call this one “I like to chop up pedestrians” — also thats the smallest number plate I’ve ever seen.
More lights = Better
Skele says Hi.

Free books and other news

Allan Kelly from Allan Kelly Associates

3Books-2018-06-4-10-31.jpg

Many of you are reading this because you signed-up for a free copy of my Xanpan book.

Thank you so much! – I hope you are enjoying my thoughts, reflections and tips.

Now, can I ask a favour, please? – a few minutes of your time.

If you have a copy of Xanpan would you mind writing me an Amazon review? (thats .com, Amazon UK has a separate list of reviews – yes, it is a pain).

Please, please, please 🙂

Amazon reviews make a big difference to sales and I’d be most grateful. (Even more so for 5-star reviews!)

And I will happily give a free review copy of “Little Book of Requirements and User Stories” to anyone who would like to review that book too – mail me, allan@allankelly.net. (And if you already have a copy of Little Book please suggest some other way I can thank you for your review.)

I’m also working on getting Continuous Digital and Project Myopia onto Amazon. Both will get new professional covers and a proper copy edit

Finally, as some of you know, I’ve started writing a companion to Little Book: Product Ownership. Again I’m using the LeadPub system so you can buy the book now and get free updates as I add to the book and edit it. And I am most grateful to those of you who have already bought Product Ownership.

The post Free books and other news appeared first on Allan Kelly Associates.

EDG and Github are both logical purchases for Microsoft

Derek Jones from The Shape of Code

It looks like my prediction that Microsoft buys Github may be about to come true.

Microsoft has been sluggish in integrating their LinkedIn purchase into their identity management system. Lots of sites have verify identity using Github options (or at least the kind of sites I visit do), so perhaps LinkedIn identity will be trialed via Github.

A Github purchase will also allow Microsoft to directly connect lots of developers to Azure. Being able to easily build and execute Github code on Azure is the bait, customer data is where the money is; making Github more data friendly is an obvious first priority for new owners.

Who else should Microsoft buy? As a protective move, I think they should snap up Edison Design Group (EDG) before somebody else does. Readers outside of the compiler/static analysis/C++ standards world are unlikely to have heard of EDG. They sell C/C++ front ends (plus other languages) that support all the historical features/warts supported by other C/C++ compilers. The features only found in Microsoft’s compilers is what make it very costly/time-consuming for many companies to port their applications to other platforms; developer use of Microsoft compiler dependent features is a moat that makes it difficult for many companies to leave the Microsoft ecosystem. EDG have been in the business a long time and have built up an extensive knowledge of vendor specific compiler features; the kind of knowledge that can only be obtained by having customers tell you what language constructs they are using that your current product does not handle (and what those constructs actually mean).

What would happen if a very large company bought EDG, and open sourced its code (to make it easier for Windows developers to switch platforms, not to make any money off compiler related tools)? Somebody would have to bolt on a back-end, to generate code; but that would not be hard (EDG have designed their product to make this easy). A freely available compiler, supporting all/most of the foibles of the Microsoft C++ compiler, would tempt many Windows only developers to give it a go. A free compiler removes management from the loop, developers can try things out as a side project, without having to get management approval to spend money on a compiler (from practical experience I know how hard it is to sell compatible compiler products, i.e., there is no real money to be made by anybody doing this commercially).

Is this risk, to Microsoft, really worth the (relatively) low cost of buying EDG? The EDG guys are not getting any younger, why wouldn’t they be willing sell?

Chalk The Lines – a.k.

a.k. from thus spake a.k.

Given a set of points (xi,yi), a common problem in numerical analysis is trying to estimate values of y for values of x that aren't in the set. The simplest scheme is linear interpolation, which connects points with consecutive values of x with straight lines and then uses them to calculate values of y for values of x that lie between those of their endpoints.
On the face of it implementing this would seem to be a pretty trivial business, but doing so both accurately and efficiently is a surprisingly tricky affair, as we shall see in this post.