Download article as PDF file from Elsevier’s ScienceDirect via command line (curl)

When not in the office, we often times cannot directly access scientific literature, because access control is usually based on IP addresses. However, we usually have SSH access to the university network. Being logged in to a machine in the university network we should — in theory — be able to access a certain article. Most of the times it is the PDF file that we are interested in and not the “web page” corresponding to an article. So, can’t we just $ curl to get that file? Most of the times, this does not work, because access to journal articles usually happens through rather complex web sites, such as Elsevier’s ScienceDirect:

ScienceDirect is a leading full-text scientific database offering journal articles and book chapters from nearly 2,500 journals and 26,000 books.

Such web sites add a considerable amount of complexity to the technical task of downloading a file. The problem usually starts with obtaining the direct URL to the PDF file. Also, HTTP redirection and cookies are usually involved. Often times, the only solution people see to solve these issues is to set up a VPN and then to use a fully fledged browser through that VPN, and let the browser deal with the complexity.

However, I prefer to get back to the basics and always strive to somehow find a direct URL to the PDF file to then download it via curl or wget.

This is my solution for Elsevier’s ScienceDirect:

Say, for instance, you wish to download the PDF version of this article:

Then all you need is that URL and the following commands executed on a common Linux system:

export SDURL=""
curl -Lc cookiejar "${SDURL}" | grep pdfurl | perl -pe 's|.* pdfurl=\"(.*?)\".*|\1|' > pdfurl
curl -Lc cookiejar "$(cat pdfurl)" > article.pdf

The method first parses the HTML source code of the main page corresponding to the article and extracts a URL to the PDF file. At the same time, it also stores the HTTP cookie(s) set by the web server when accessing named web page. These cookies are then re-used when accessing the PDF file directly. This has reproducibly worked for me.

If it does not work for you, I recommend having a look into the file pdfurl and see if that part of the process has lead to a meaningful result or not. Obviously, the second step can only succeed aver having obtained a proper URL to the PDF file.

This snippet should not be treated as a black box. Please execute it in an empty directory. Also note that this snippet only works subject to the condition that ScienceDirect keeps functioning the way it does right now (which most likely is the case for the next couple of months or years).

Don’t hesitate to get back to me if you have any questions!

gipc 0.6.0 released

I have just released gipc 0.6.0 introducing support for Python 3. This release has been motivated by gevent 1.1 being just around the corner, which will also introduce Python 3 support.

Changes under the hood

The new gipc version has been verified to work on CPython 2.6.9, 2.7.10, 3.3.6, and 3.4.3. Python 3.4 support required significant changes under the hood: internally, gipc uses multiprocessing.Process, whose implementation drastically changed from Python 3.3 to 3.4. Most notably, on Windows, the arguments to the hard-coded CreateProcess() system call were changed, preventing automatic inheritance of file descriptors. Hence, implementation of a new approach for file descriptor transferral between processes was required for supporting Python 3.4 as well as future Python versions. Reassuringly, the unit test suite required close-to-zero adjustments.

The docs got a fresh look

I have used this opportunity to amend the documentation: it now has a fresh look based on a brutally modified RTD theme. This provides a much better reading experience as well as great support for narrow screens (i.e. mobile support). I hope you like it:

Who’s using gipc?

I have searched the web a bit for finding interesting use cases. These great projects use gipc:

Are you successfully applying gipc in production? That is always great to hear, so please drop me a line!


As usual, the release is available via PyPI ( Please visit for finding API documentation, code examples, installation notes, and further in-depth information.

WP-GeSHi-Highlight 1.3.0 released

I have released version 1.3.0 of WP-GeSHi-Highlight. WP-GeSHi-Highlight is a popular code syntax highlighting plugin for WordPress, based on the established PHP highlighting library GeSHi.

These are the changes compared to version 1.2.3:

  • Enhance compatibility of the default stylesheet with a large range of themes by increasing the specificity of certain CSS selectors and by adding more style directives. This ensures a better out-of-the-box experience. Thanks to Pascal Krause for reporting an incompatilibity with Twenty Ten.
  • Increase compatibility with CDNs: fix double slash appearing in CSS file URL.
  • Remove redundant call to wp_register_style().
  • Change style sheet ID prefix, add newline characters to GeSHi CSS code output.
  • Improve code documentation and readability.

In fact, this update contains a considerably consolidated default stylesheet (with just a minimal set of changes). I have verified that it works well with all recent versions of the important official themes:

  • Twenty Ten (version 1.9)
  • Twenty Eleven (version 2.1)
  • Twenty Twelve (version 1.7)
  • Twenty Thirteen (version 1.5)
  • Twenty Fourteen (version 1.4)
  • Twenty Fifteen (version 1.2)

I have also tested the new default style sheet with the following popular themes: Vantage, Customizr, ColorWay, Zerif Lite, Responsive, Storefront, Virtue, evolve, Make, Sparkling, Spacious, Enigma, Sydney, Point, Interface, SinglePage.

I want to use this opportunity to stress how much I like the recent community developments around WP-GeSHi-Highlight. Almost five years have passed since I first released this plugin to the WP repository, and I never really put effort into spreading it. Nevertheless, according to the WordPress statistics, it is used on more than one thousand websites. I have searched the web to find a few examples about who uses this plugin for which purpose, and want to share two of my findings:

  • In this StackOverflow thread, Aaron Bertrand, a ninja database expert, revealed that he likes the GeSHi-based approach so much (and he uses WP-GeSHi-Highlight in his blogs), that he was willing to provide a huge bounty to someone helping him out to improve the syntax highlighting for the T-SQL language in subtle ways. Another ninja joined the discussion for helping Aaron, and Aaron had more wishes like “There’s always one little extra thing, right? I promise this is it. I want to color the N prefix on Unicode strings in red.”. They found their solution, great. I proposed to them to contribute their findings upstream, straight to GeSHi, so that I, further downstream, can incorporate them in WP-GeSHi-Highlight at some point. I love this.

  • On Make Create Reiterate, Tina Dvyver uses WP-GeSHi-Highlight (and writes about it) as of its support for an exotic language in the world of highlighters, X++. What I like about her blog is that she actually took her time to adjust the default stylesheet to her needs, and that she came up with a neat way to hide the dots in the numbered list, when using line numbering. She writes about it here.

One more thing I want to mention: in the past days I had a productive discussion with two users of this plugin, in this support thread. Turns out that WP-GeSHi-Highlight was not responsible for the issue reported there, but this discussion still lead to fixing the double-slash issue mentioned above in the change log. It also lead to me knowing of one more person who actively transitioned from WP-Syntax to WP-GeSHi-Highlight, and to one more review on the plugin page.

I realize that I should put more effort into spreading this plugin, as it has obvious architectural advantages over heavy client-side highlighters. Unfortunately, most of the “Top X syntax highlighting plugins for WordPress” blog posts around the web do not really clarify the significant difference between back-end highlighters and client-side ones. I’ll possibly cover that in a future blog post.

Git: list authors sorted by the time of their first contribution

I have created a micro Python script, git-authors, which parses the output of git log and outputs the authors in order of their first contribution to the repository.

By itself, this is a rather boring task. However, I think the resulting code is quite interesting, because it applies a couple of really important concepts and Python idioms within just a couple of lines. Hence, this small piece of code is not only useful in practice; it also serves an educational purpose.

The latter is what this article focuses on. What can you expect to learn? Less than ten lines of code are discussed. Center of this discussion is efficient stream processing and proper usage of data structures: with a very simple and yet efficient architecture, git-authors can analyze more than 500.000 commits of the Linux git repository with near-zero memory requirements and consumption of only 1 s of CPU time on a weak machine.

Usage: pipe formatted data from git log to git-authors

The recommended usage of git-authors is:

$ git log --encoding=utf-8 --full-history --reverse "--format=format:%at;%an;%ae" | \
    git-authors > authors-by-first-contrib.txt

A little background information might help for understanding this. git-authors expects to be fed with a data stream on standard input (stdin), composed of newline-separated chunks. Each chunk (line) is expected to represent one commit, and is expected to be of a certain format:


Furthermore, git-authors expects to retrieve these commits sorted by time, ascendingly (newest last).

git log can be configured to output the required format (via --format=format:%at;%an;%ae) and to output commits sorted by time (default) with the earliest commits first (using --reverse).

git log writes its output data to standard output (stdout). The canonical method for connecting stdout of one process to stdin of another process is a pipe, a transport mechanism provided by the operating system.

The command line options --encoding=utf-8 and --full-history should not be discussed here, for simplicity.

The input evaluation loop

Remember, the git-authors program expects to retrieve a data stream via stdin. An example snippet of such a data stream could look like this:

1113690343;Bert Wesarg;
1113690343;Ken Chen;
1113690344;Christoph Hellwig;
1113690345;Bernard Blackham;
1113690346;Jan Kara;

The core of git-authors is a loop construct built of seven lines of code. It processes named input stream in a line-by-line fashion. Let’s have a look at it:

  1. seen = set()
  2. for line in stdin:
  3.     timestamp, name, mail = line.strip().split(";")
  4.     if name not in seen:
  5.         seen.add(name)
  6.         day = time.strftime("%Y-%m-%d", time.gmtime(float(timestamp)))
  7.         stdout.write("%04d (%s): %s (%s)\n" % (len(seen), day, name, mail))

There are a couple of remarks to be made about this code:

  • This code processes the stream retrieved at standard input in a line-by-line fashion: in line 2, the script makes use of the fact that Python streams (implemented via IOBase) support the iterator protocol, meaning that they can be iterated over, whereas a single line is yielded from the stream upon each iteration (until the resource has been entirely consumed).

  • The data flow in the loop is constructed in a way that the majority of the payload data (the line’s content) is processed right away and not stored for later usage. This is a crucial concept, ensuring a small memory footprint and, even more important, a memory footprint that does (almost) not depend on the size of the input data (which also means that the memory consumption becomes largely time-independent). The minimum amount of data that this program requires to keep track of across loop iterations is a collection of unique author names already seen (repetitions are to be discarded). And that is exactly what is stored in the set called seen. How large might this set become? An estimation: how many unique author names will the largest git project ever accumulate? A couple of thousand maybe? As of summer 2015, the Linux git repository counts more than half a million commits and about 13.000 unique author names. Linux should have one of the largest if not the largest git history. It can safely be assumed that O(10^5) short strings is the maximum amount of data this program will ever need to store in memory. How much memory is required for storing a couple of thousand short strings in Python? You might want to measure this, but it is almost nothing, at least compared to how much memory is built into smartphones. When analyzing the Linux repository, the memory footprint of git-authors stayed well below 10 MB.

  • Line 3 demonstrates how powerful Python’s string methods are, especially when cascaded. It also shows how useful multiple assignment via sequence unpacking can be.

  • “Use the right data structure(s) for any given problem!” is an often-preached rule, for ensuring that the time complexity of the applied algorithm is not larger than the problem requires. Lines 1, 4, and 5 are a great example for this, I think. Here, we want to keep track of the authors that have already been observed in the stream (“seen”). This kind of problem naturally requires a data structure allowing for lookup (Have I seen you yet?) and insert (I’ve seen you!) operations. Generally, a hash table-like data structure fits these problems best, because it provides O(1) (constant) complexity for both, lookup and insertion. In Python, the dictionary implementation as well as the set implementation are both based on a hash table (in fact, these implementations share a lot of code). Both dicts and sets also provide a len() method of constant complexity, which I have made use of in line 7. Hence, the run time of this algorithm is proportional to the input size (to the number of lines in the input). It is impossible to scale better than that (every line needs to be looked at), but there are many sub-optimal ways to implement a solution that scales worse than linearly.

  • The reason why I chose to use a set instead of a dictionary is rather subtle: I think the add() semantics of set fit the given problem really well, and here we really just want to keep track of keys (the typical key-value association of the dictionary is not required here). Performance-wise, the choice shouldn’t make a significant difference.

  • Line 6 demonstrates the power of the time module. Take a Unix timestamp and generate a human-readable time string from it: easy. In my experience, strftime() is one of the most-used methods in the time module, and learning its format specifiers by heart can be really handy.

  • Line 7: old-school powerful Python string formatting with a very compact syntax. Yes, the “new” way for string formatting (PEP 3101) has been around for years, and deprecation of the old style was once planned. Truth is, however, that the old-style formatting is just too beloved and established, and will probably never even become deprecated, let alone removed. Its functionality was just extended in Python 3.5 via PEP 461.

Preparation of input and output streams

What is not shown in the snippet above is the preparation of the stdin and stdout objects. I have come up with the following method:

kwargs = {"errors": "replace", "encoding": "utf-8", "newline": "\n"}
stdin =, **kwargs)
stdout =, mode="w", **kwargs)

This is an extremely powerful recipe for obtaining the same behavior on Python 2 as well as on 3, but also on Windows as well as on POSIX-compliant platforms. There is a long story behind this which should not be the focus of this very article. In essence, Python 2 and Python 3 treat sys.stdin/sys.stdout very differently. Grabbing the underlying file descriptors by their balls via fileno() and creating TextIOWrapper stream objects on top of them is a powerful way to disable much of Python’s automagic and therefore to normalize behavior among platforms. The automagic I am referring to here especially includes Python 3’s platform-dependent automatic input decoding and output encoding, and universal newline support. Both really can add an annoying amount of complexity in certain situations, and this here is one such case.

Example run on CPython’s (inofficial) git repository

I applied git-authors to the current state of the inofficial CPython repository hosted at GitHub. As a side node, this required about 0.1 s of CPU time on my test machine. I am showing the output in full length below, because I find its content rather interesting. We have to appreciate that the commit history is not entirely broken, despite CPython having switched between different version control systems over the last 25 years. Did you know that Just van Rossum also was a committer? :-)

0001 (1990-08-09): Guido van Rossum (
0002 (1992-08-04): Sjoerd Mullender (
0003 (1992-08-13): Jack Jansen (
0004 (1993-01-10): cvs2svn (
0005 (1994-07-25): Barry Warsaw (
0006 (1996-07-23): Fred Drake (
0007 (1996-12-09): Roger E. Masse (
0008 (1997-08-13): Jeremy Hylton (
0009 (1998-03-03): Ken Manheimer (
0010 (1998-04-09): Andrew M. Kuchling (
0011 (1998-12-18): Greg Ward (
0012 (1999-01-22): Just van Rossum (
0013 (1999-11-07): Greg Stein (
0014 (2000-05-12): Gregory P. Smith (
0015 (2000-06-06): Trent Mick (
0016 (2000-06-07): Marc-André Lemburg (
0017 (2000-06-09): Mark Hammond (
0018 (2000-06-29): Fredrik Lundh (
0019 (2000-06-30): Skip Montanaro (
0020 (2000-06-30): Tim Peters (
0021 (2000-07-01): Paul Prescod (
0022 (2000-07-10): Vladimir Marangozov (
0023 (2000-07-10): Peter Schneider-Kamp (
0024 (2000-07-10): Eric S. Raymond (
0025 (2000-07-14): Thomas Wouters (
0026 (2000-07-29): Moshe Zadka (
0027 (2000-08-15): David Scherer (
0028 (2000-09-07): Thomas Heller (
0029 (2000-09-08): Martin v. Löwis (
0030 (2000-09-15): Neil Schemenauer (
0031 (2000-09-21): Lars Gustäbel (
0032 (2000-09-24): Nicholas Riley (
0033 (2000-10-03): Ka-Ping Yee (
0034 (2000-10-06): Jim Fulton (
0035 (2001-01-10): Charles G. Waldman (
0036 (2001-03-22): Steve Purcell (
0037 (2001-06-25): Steven M. Gava (
0038 (2001-07-04): Kurt B. Kaiser (
0039 (2001-07-04): unknown (
0040 (2001-07-20): Piers Lauder (
0041 (2001-08-23): Finn Bock (
0042 (2001-08-27): Michael W. Hudson (
0043 (2001-10-31): Chui Tey (
0044 (2001-12-19): Neal Norwitz (
0045 (2001-12-21): Anthony Baxter (
0046 (2002-02-17): Andrew MacIntyre (
0047 (2002-03-21): Walter Dörwald (
0048 (2002-05-12): Raymond Hettinger (
0049 (2002-05-15): Jason Tishler (
0050 (2002-05-28): Christian Tismer (
0051 (2002-06-14): Steve Holden (
0052 (2002-09-23): Tony Lownds (
0053 (2002-11-05): Gustavo Niemeyer (
0054 (2003-01-03): David Goodger (
0055 (2003-04-19): Brett Cannon (
0056 (2003-04-22): Alex Martelli (
0057 (2003-05-17): Samuele Pedroni (
0058 (2003-06-09): Andrew McNamara (
0059 (2003-10-24): Armin Rigo (
0060 (2003-12-10): Hye-Shik Chang (
0061 (2004-02-18): David Ascher (
0062 (2004-02-20): Vinay Sajip (
0063 (2004-03-21): Nicholas Bastin (
0064 (2004-03-25): Phillip J. Eby (
0065 (2004-08-04): Matthias Klose (
0066 (2004-08-09): Edward Loper (
0067 (2004-08-09): Dave Cole (
0068 (2004-08-14): Johannes Gijsbers (
0069 (2004-09-17): Sean Reifschneider (
0070 (2004-10-16): Facundo Batista (
0071 (2004-10-21): Peter Astrand (
0072 (2005-03-28): Bob Ippolito (
0073 (2005-06-03): Georg Brandl (
0074 (2005-11-16): Nick Coghlan (
0075 (2006-03-30): Ronald Oussoren (
0076 (2006-04-17): George Yoshida (
0077 (2006-04-23): Gerhard Häring (
0078 (2006-05-23): Richard Jones (
0079 (2006-05-24): Andrew Dalke (
0080 (2006-05-25): Kristján Valur Jónsson (
0081 (2006-05-25): Jack Diederich (
0082 (2006-05-26): Martin Blais (
0083 (2006-07-28): Matt Fleming (
0084 (2006-09-05): Sean Reifscheider (
0085 (2007-03-08): Collin Winter (
0086 (2007-03-11): Žiga Seilnacht (
0087 (2007-06-07): Alexandre Vassalotti (
0088 (2007-08-16): Mark Summerfield (
0089 (2007-08-18): Travis E. Oliphant (
0090 (2007-08-22): Jeffrey Yasskin (
0091 (2007-08-25): Eric Smith (
0092 (2007-08-29): Bill Janssen (
0093 (2007-10-31): Christian Heimes (
0094 (2007-11-10): Amaury Forgeot d'Arc (
0095 (2008-01-08): Mark Dickinson (
0096 (2008-03-17): Steven Bethard (
0097 (2008-03-18): Trent Nelson (
0098 (2008-03-18): David Wolever (
0099 (2008-03-25): Benjamin Peterson (
0100 (2008-03-26): Jerry Seutter (
0101 (2008-04-16): Jeroen Ruigrok van der Werven (
0102 (2008-05-13): Jesus Cea (
0103 (2008-05-24): Guilherme Polo (
0104 (2008-06-01): Robert Schuppenies (
0105 (2008-06-10): Josiah Carlson (
0106 (2008-06-10): Armin Ronacher (
0107 (2008-06-18): Jesse Noller (
0108 (2008-06-23): Senthil Kumaran (
0109 (2008-07-22): Antoine Pitrou (
0110 (2008-08-14): Hirokazu Yamamoto (
0111 (2008-12-24): Tarek Ziadé (
0112 (2009-03-30): R. David Murray (
0113 (2009-04-01): Michael Foord (
0114 (2009-04-11): Chris Withers (
0115 (2009-05-08): Philip Jenvey (
0116 (2009-06-25): Ezio Melotti (
0117 (2009-08-02): Frank Wierzbicki (
0118 (2009-09-20): Doug Hellmann (
0119 (2010-01-30): Victor Stinner (
0120 (2010-02-23): Dirkjan Ochtman (
0121 (2010-02-24): Larry Hastings (
0122 (2010-02-26): Florent Xicluna (
0123 (2010-03-25): Brian Curtin (
0124 (2010-04-01): Stefan Krah (
0125 (2010-04-10): Jean-Paul Calderone (
0126 (2010-04-18): Giampaolo Rodolà (
0127 (2010-05-26): Alexander Belopolsky (
0128 (2010-08-06): Tim Golden (
0129 (2010-08-14): Éric Araujo (
0130 (2010-08-22): Daniel Stutzbach (
0131 (2010-09-18): Brian Quinlan (
0132 (2010-11-05): David Malcolm (
0133 (2010-11-09): Ask Solem (
0134 (2010-11-10): Terry Reedy (
0135 (2010-11-10): Łukasz Langa (
0136 (2012-06-24): Ned Deily (
0137 (2011-01-14): Eli Bendersky (
0138 (2011-03-10): Eric V. Smith (
0139 (2011-03-10): R David Murray (
0140 (2011-03-12): orsenthil (
0141 (2011-03-14): Ross Lagerwall (
0142 (2011-03-14): Reid Kleckner (
0143 (2011-03-14): briancurtin (
0144 (2011-03-24): guido (
0145 (2011-03-30): Kristjan Valur Jonsson (
0146 (2011-04-04): brian.curtin (
0147 (2011-04-12): Nadeem Vawda (
0148 (2011-04-19): Giampaolo Rodola' (
0149 (2011-05-04): Alexis Metaireau (
0150 (2011-05-09): Gerhard Haering (
0151 (2011-05-09): Petri Lehtinen (
0152 (2011-05-24): Charles-François Natali (
0153 (2011-07-17): Alex Gaynor (
0154 (2011-07-27): Jason R. Coombs (
0155 (2011-08-02): Sandro Tosi (
0156 (2011-09-28): Meador Inge (
0157 (2012-01-09): Terry Jan Reedy (
0158 (2011-05-19): Tarek Ziade (
0159 (2011-05-22): Martin v. Loewis (
0160 (2011-05-31): Ralf Schmitt (
0161 (2011-09-12): Jeremy Kloth (
0162 (2012-03-14): Andrew Svetlov (
0163 (2012-03-21): krisvale (
0164 (2012-04-24): Marc-Andre Lemburg (
0165 (2012-04-30): Richard Oudkerk (
0166 (2012-05-15): Hynek Schlawack (
0167 (2012-06-20): doko (
0168 (2012-07-16): Atsuo Ishimoto (
0169 (2012-09-02): Zbigniew Jędrzejewski-Szmek (
0170 (2012-09-06): Eric Snow (
0171 (2012-09-25): Chris Jerdonek (
0172 (2012-12-27): Serhiy Storchaka (
0173 (2013-03-31): Roger Serwy (
0174 (2013-03-31): Charles-Francois Natali (
0175 (2013-05-10): Andrew Kuchling (
0176 (2013-06-14): Ethan Furman (
0177 (2013-08-12): Felix Crux (
0178 (2013-10-21): Peter Moody (
0179 (2013-10-25): bquinlan (
0180 (2013-11-04): Zachary Ware (
0181 (2013-12-02): Walter Doerwald (
0182 (2013-12-21): Donald Stufft (
0183 (2014-01-03): Daniel Holth (
0184 (2014-01-27): Yury Selivanov (
0185 (2014-04-15): Kushal Das (
0186 (2014-06-29): Berker Peksag (
0187 (2014-07-16): Tal Einat (
0188 (2014-10-08): Steve Dower (
0189 (2014-10-18): Robert Collins (
0190 (2015-03-22): Paul Moore (


Similar functionality is provided by the more full-blown frameworks grunt-git-authors and gitstats.

Some resources that might be insightful for you:

Insights into SoundCloud culture

SoundCloud (cf. Wikipedia) is a young Berlin-based company “under the laws of England & Wales”, and with Swedish origin. Six years ago, in 2009, they acquired their first big funding. Since then, they experienced a tremendous growth and were able to regularly raise investment capital. Until today, SoundCloud has created and put itself into a unique position with a convincing product (which I am using — and paying — myself), but can also be considered as competitor of big brands such as Spotify and Beats Music. In fact, according to the Wall Street Journal, SoundCloud can be expected to join the party of billion-dollar IT companies quite soon:

SoundCloud, a popular music and audio-sharing service, is in discussions to raise about $150 million in new financing at a valuation that is expected to top $1.2 billion, according to two people with knowledge of the negotiations.

Having these facts in mind, it is impressive to hear that SoundCloud still only employs 300 people, in just a handful of offices around the world. Just like me, you might be curious about getting to know details of this kind, and about the SoundCloud story in itself. So, I was really eager to listen to Episode 17 of “Hipster & Hack“, featuring an interview with David Noël (Twitter profile, LinkedIn profile). David has accompanied SoundCloud for six years now and currently leads Internal Communications. He clearly is in the position to provide authoritative information about how SoundCloud’s vision was translated into reality over time, but also about how culture and communication within SoundCloud evolved. The latter is what he mainly talks about in the interview, providing insights about the structure and tools applied for defining a culture, for keeping it under control, and for communicating it to employees from the very first moment on until even after they have left the company. David defines culture as the living manifestation of core values and comes to insightful statements such as

Living your values is your culture at any moment in time.

In the interview, we learn that one of SoundCloud’s core values is being open, in the context of internal communications. The culture and communication topic really seems to have a high priority in the company, judging based on methods like the “all-hands” meeting that David refers to in the interview. Personally, I cannot overstate how much I value this, coming from classical research where such elements are often just neglected.

So, if that raises your interest, I recommend listening to three quite likable guys here (listening to minutes 4 to 29 suffices, the rest is enjoyable overhead ;-)):