Multi-Page Blueprints for Confluence
A free demo app is available in the Atlassian Marketplace which supports multi-page blueprints for Confluence. This app works around numerous bugs in the official Atlassian blueprint tutorials and a key Atlassian API bug.
Background on Confluence
Confluence is one of the leading enterprise wiki products. Its built-in feature set is already very powerful, and it can be extended with applications available in the Atlassian Marketplace. You can also write your own applications for private, internal use. Atlassian provides the atlassian-connect-express toolkit for building apps with Node.js, which reduces development time and effort. They also provide a number of sample projects for Jira and Confluence apps on Bitbucket. Unfortunately, many of these examples are obsolete or deprecated, and do not function correctly with the latest version of atlassian-connect-express or the latest release of Confluence and Jira.
Node.js: Connecting to MySQL on a socket with Sequelize
According to its official description, “Sequelize is a promise-based Node.js ORM for Postgres, MySQL, MariaDB, SQLite and Microsoft SQL Server.” Sequelize is widely used in Node.js web applications to abstract the database layer. I recently found a “corner case” for Sequelize which is possible to accomplish, but is not well documented anywhere on the web. I need to use Sequelize to connect to a MySQL server via a UNIX socket. I’m developing some plugins for Confluence that use the atlassian-connect-express toolkit, which has a datastore that wraps Sequelize. The way Atlassian has chosen to wrap Sequelize is rather unfortunate, probably because they are trying to maintain backwards compatibility with JugglingDB. Essentially, the Atlassian Connect Express only looks at the URL, and ignores any option passed to Sequelize. Therefore, you have to pass everything you need via the URL, and this is where it’s tricky. Here’s the form of the URL that you need to connect to MySQL via a UNIX socket with Sequelize:
Configuring Laravel/Lumen applications to connect to SQL database sockets
The Laravel/Lumen framework documentation does not explain how to connect an application to a database using UNIX sockets instead of a TCP-based network connection. I recently had to configure the Polr URL shortener (built on the Lumen microframework by Laravel) to connect to Google Cloud SQL with a UNIX socket. Since all of Polr’s configuration takes place in the .env file, and there is no environment variable that’s specific to database sockets, this took some research. I finally found the answer in an obscure StackOverflow response. Previous TCP connection: [code] DB_HOST=some-server-name DB_PORT=3306 [/code] Socket-based SQL connection: [code] DB_HOST=localhost;unix_socket=/cloudsql/cloud-project-name:us-east1:sql-instance-name [/code] This approach will work with any UNIX socket; you just need to give it the absolute path to the socket.
Service account credentials with the Python client for the Google Drive API (v3)
EDIT: Get the full code for this post on Github. This article only contains important snippets of code that require explanation.
There are numerous ways to authenticate against the Google Drive API. If you have an application running on Google Compute Engine that needs to access Drive, a Service Account is probably the easiest way to do it. One use case is for an application to write reports or log files to Drive so that users can see them without logging into a server. Before you try this example, go through all of the steps in Google’s Using OAuth 2.0 for Server to Server Applications guide and save your service account’s private key locally in JSON format. Getting credentials from a service account file is easy:
"Exporting" a project from a Git repository
What do you do when you want to distribute or release source code that is stored in a Git repository? Obviously, if your target audience is using Git, you can just compress the directory that contains the repository and distribute the copies, or give the users a way to clone your repository (such as GitHub). However, your audience may not be Git users, or the hidden .git directory may be very large and you don’t want to distribute it. The solution is the git archive command, which packs the files from a tree-ish into an achive (ZIP or TAR). By “tree-ish”, they mean that you can specify a branch, commit, HEAD, etc. git archive is somewhat analagous to the svn export command. I find the most useful form of this command to be: cd example git archive --output ~/example.zip --format=zip --prefix=example/ HEAD Do not forget the trailing slash after the directory that you specify with the --prefix flag! REFERENCE: How to do a “git export” (like svn export)
Collaborative Git workflow: Shared Repository on a File Server
GitHub is a great tool for collaborating on projects. However, sometimes it is necessary to mimic the “GitHub workflow” using a shared repository on a local Linux server. The following example shows how I shared an example repository with multiple users. We are also using the Git flow model for branching, aided by the handy git flow plugin.
On my workstation
I started by creating a repo on my local workstation and setting it up to use the git flow plugin.
pickle, hickle and HDF5
Danny Price recently left a comment to let me know about a new Python package he’s developing called hickle. The goal of “hickle” is to create a module that works like Python’s pickle module but stores its data in the HDF5 binary file format. This is a promising approach, because I advocate storing binary data in HDF5 files whenever possible instead of creating yet another one-off binary file format that nobody will be able to read in ten years. The immediate advantage of using HDF5 to store picked Python objects is that HDF5 files are portable across many platforms, while “pickled” objects may not be readable on a different platform. The hickle developers have made a good start, and they have a long way to go before hickle will be useful to a wider audience. Right now, hickle can only store NumPy ndarrays and Python list objects. If you only need to store lists and arrays, you might as well use HDF5 bindings for Python such as PyTables or h5py. The power of the pickle module is that you can immediately serialize almost any Python object of arbitrary complexity, store it on disk, and retrieve it. hickle will only achieve its full potential once it replicates this functionality, and I’m not sure how difficult this will be. Ideally, you might be able to derive a class from Pickler that uses Picker’s methods to serialize an object, and then add your own method to write the serialized object to an HDF5 file. In a future post, I’ll describe some of the practical problems with using pickle files to store data, and try to organize some thoughts about how they might be solved.
Tricks for Writing XML with Python 3
I’ve added a Python 3 XML example to my Shocksolution_Examples repo on GitHub. The new example shows how to generate an XML file which functions as a template for building a GUI with wxGlade. However, this example should be helpful for anyone who needs to create XML files with Python. The full example is on GitHub, so I’m just going to highlight a few interesting snippets. Use the SubElement factory function to create a new Element instance and add it to an existing element. Here, I create an element called templatedata and add it to the root element. I then create another element called author and add it to templatedata.
Python string format examples
The format method for Python strings (introduced in 2.6) is very flexible and powerful. It’s also easy to use, but the documentation is not very clear. It all makes sense with a few examples. I’ll add more as I have time:
Formatting Numbers in Python Strings
Formatting a floating-point number
[code language=“python”] “{0:.4f}".format(0.1234567890) “{0:.4f}".format(10.1234567890) [/code] The result is the following string:
'0.1235'
'10.1235'Braces { } are used to enclose the “replacement field” 0 indicates the first argument to method format : indicates the start of the format specifier .4 indicates four decimal places f indicates a floating-point number