Connecting to Slack from an IRC client using slirc

Andy Balaam from Andy Balaam's Blog

I tried to get back to an IRC interface to Slack using Matrix, and it had some problems. Thanks to Colin Watson’s comment on that post, I tried Daniel Beer’s slirc, and so far it seems to be working pretty well.

Here’s what I did:

Get a Slack legacy token which slirc 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 the prerequisites for slirc, and download it:

sudo cpan AnyEvent AnyEvent::HTTP AnyEvent::Socket AnyEvent::WebSocket::Client URI::Encode Data::Dumper JSON
mkdir slirc
cd slirc
wget -q 'https://www.dlbeer.co.nz/articles/slirc/slirc-20180515.pl'
chmod +x slirc-20180515.pl

Create a file in the slirc directory you created above, called rc.conf, and make it look like this:

slack_token=abcd-123456768-ETC-ETC
password=somepassword
port=6667

Replace “abcd-123456768-ETC-ETC” with the Slack legacy token you noted down earlier.

Replace “somepassword” with something you’ve made up (not your Slack password) – this is what you will type as the password in your IRC client.

Run slirc and leave it running:

./slirc-20180515.pl rc.conf

(Make sure you are inside the slirc dir when you run that.)

Start your IRC client (e.g. HexChat) and add a server with address “localhost” and port 6667, with your slack username and the password you added in the rc.conf (which you wrote instead of “somepassword”).

This mostly works for me, except it has a tendency to open a load of ad-hoc chats as channels, so I have to close them all to get a usable list.

Main memory: the crucial component that vendors don’t mention

Derek Jones from The Shape of Code

CPU performance hogs the limelight when people discuss the year-on-year increases in computing power that used to occur.

This focus on cpu performance was/is driven by marketing, the people with the money either don’t want customers thinking about the performance impact of main memory size or speed, or want them to treat the processor as the most important component of a computer. Vendors want processor performance to drive customer purchase decisions.

Hardware manufacturers used to entice new customers with low cost machines, containing minimal memory. Once a customer started to use their shiny new computer, they found that it did save them lots of time and money, but also they needed more memory (which could only be brought from the manufacturer and was not cheap).

The plot below shows the prices IBM charged for System 360s, in 1966. Anti-trust investigations uncover all kinds of interesting data, like selling low-spec equipment at a loss to entice customers and make life difficult for competitors (code+data for all plots).

Profit margin on IBM 360s sold with various memory sizes

The plot below (data from the 19 Aug 1985 issue of ComputerWorld) shows how the price of computers increased as the minimum about of memory they supported increased.

Yes, in 1985 top end computers came with over 50M of memory; but most customers thought themselves lucky if they had a few megabytes.

If the processor is slow, it just takes longer for programs to run. If the computer does not have enough memory, programs cannot run. For most applications memory requirements are addressed first, followed by processor performance; memory requirements is the number one issue. The optimizations that commercial compilers could perform were limited by the memory capacity of developer machines.

List price of computers, in 1985, supporting the given minimum amount of  memory

Intel’s main line of business used to be selling memory chips, but these chips became commodity items as more companies entered the market; Intel bet the farm on selling processors and the rest is history. As a seller of a unique product it was/is in Intel’s interest to spend lots of money on marketing the benefits of processor performance; sellers of commodity items (such as memory chips) don’t have nearly as much to gain from generic product marketing, because customers may choose to buy from other sellers (in such markets sellers have to concentrate on marketing themselves).

Memory capacity/speed and cpu speed are two aspects of system performance; they need to be balanced to meet customer drive application requirements. The plot below shows the SPEC cpu integer performance of 4,332 systems running at various clock rates; the colors denote the different peak memory transfer rates of the memory chips in these systems (code+data).

SPEC cpu integer performance vs. cpu clock rate

These days (and perhaps in the past, I don’t have any data), memory performance is a much better predictor of system performance, but vendors don’t have an incentive to market this fact.

Introduction to Laravel Workshop

Paul Grenyer from Paul Grenyer



When: Wednesday, 20 June 20 - 9:00am to 4:45pm

Where: Kings Centre, King Street, Norwich, NR1 1PH

How much: £85

RSVP: https://www.meetup.com/Norfolk-Developers-NorDev/events/250343445/

If you would like to start using the worlds most popular PHP framework, this is the workshop for you.

We will cover from installing Laravel to building a basic application. Everyone will learn along as we go from a freshly installed Laravel application up to creating a basic web app that interacts with a database.

Course Details

We will aim to cover the following (subject to change and class experience)

  • Routing
  • Using Blade (templating)
  • Controllers
  • Validation
  • Config/Env
  • Using Eloquent (database ORM)
  • Laravel inbuilt Auth
  • Artisan (CLI commands)
  • File Storage

Instructor

Simon Bennett is a Software Consultant who works with Laravel daily, helping clients update there development practices and coding software for startups. He also runs his own SAAS for backing up DigitalOcean servers which of course is all built with basic Laravel.

Prerequisites

This beginners workshop will run through simple code as we learn about Laravel.

Basic knowledge of PHP is required, I would recommend you know you know basic OOP.

To save time on the day, you will be contacted directly before the workshop with a guide on setting up docker. The reason we use docker is to make sure we are using identical environments on Windows/Mac/Linux.

Since Laravel used to build web-based applications (mostly), it would be helpful to a basic understanding of developing websites in PHP and MySQL.

  • Bring your Laptop
  • Have Docker installed
  • A good IDE like PHPStorm is strongly recommended
  • Working command terminal
  • A GIT client installed

TechNorwich: The End. A Story & New beginnings

Paul Grenyer from Paul Grenyer


TechNorwich: The End. A Story & New beginnings

Whitespace is sadly now having to close. Started in 2013, it was the first and largest co-working space in Norwich. Its been home to many great & successful businesses, plus home to Barclays Eagle Labs and birthplace of TechVelocity, the first accelerator for the region. Come along to this event to have a drink to remember some of the history, catch up with some of the great businesses that have lived here and discuss on the future of the amazing digital creative & tech sector in our fine city.

Get your ticket: https://technorwich.eventbrite.co.uk

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.