Optimal File Sync Source

From Optimal BPM
Jump to: navigation, search



This page is a walk-through of the code in Optimal File Sync, intended audience is developers that want to learn how to make Python/Kivy/Py4A-based applications.

Some expressions used:

  • SMB: Is the file sharing protocol used by Windows and Samba.
  • NetBIOS: A lower level communication and discovery protocol, makes networks "browseable".

The system

Very briefly, the application is a file sync app, that is used to sync files between an Android(and later iOS)-device and an SMB server. More user level information about the application is located in the Optimal_File_Sync article.

From a technical perspective it is a service/daemon that is managed using a client app. The client and the service communicate using the Open Sound Control protocol. The application has nothing to do with the synthesizers OSC was developed for, it it just a convenient format that has a simple python implementation.

The GUI app

The GUI is initialized in the main.py file, where the OptimalFileSyncApp class, a descendant of the App-class is implemented.


In its build function, the app reads settings from the ~/se.optimalbpm.optimal_file_sync folder. The name of the folder is according to the Android standard. Most significant names first. In this case the Android developer account is connected to the optimalbpm.se-domain and the name of the app is Optimal_file_sync. It uses different defaults for Android and Linux, since stuff is located differently.

In the end it brings up the GUI as defined in gui.settings.SettingsFrame by returning the instance from the build function.

How does Kivy know how the layout should look like? Well; before this, actually already on the import of the settings.py module into main.py, the Builder.load_file("gui/settings.kv") command in settings.py ran. The purpose of that was is to import a .kv file that could later be used by the SettingsFrame class.

By the way, .kv-files are written in a site-specifik language and made to easily define GUI layouts. It is highly recommended to learn how they work.

SettingsFrame/main GUI

When the main frame starts, init() is called, it:

  • loads its settings from the settings file already read in the initialization.
  • starts the osc client, makes it listen locally on port 3000.
  • initiates the clock, from now on, osc is polled for data once each second.


As mentioned before, the .kv-file has defined the layout of the application, that it should have a carousel-style interface, and so on.

However, there are several special widgets that needs a closer look.


The expand selector is the superclass for all expanding selectors. Expanding selectors has a line where a value can be edited, but also button that reveals a list view where values can be selected.


This DirSelector descends from ExpandSelector, and using a FileChooserListView it provides a way to easily select a directory or a file.


This DirSelector descends from DirSelector, and by implementing a descendant of FileSystemAbstract, FileSystemSMB, it provides a way of browsing remote file systems from Kivy.


This HostSelector descends from ExpandSelector. Using NetBIOS, it can list the available SMB-hosts on the network.

Managing the service

There is a button defined in the settings.kv-file, the button on the last page, and it is bound to the .start_service() function.

Depending on the architecture, the start_service()-function either launches an android service or just a daemon process. There is, of course, also a stop_service()-function and button, that terminates the service.

The Service/Daemon


As Py4A works, when an android service is started, it causes the main.py file to run.

In this file:

  • The SyncService class is imported
  • settings are read from the ~/se.optimalbpm.optimal_file_sync-folder
  • The service is started

Service start

  • The osc server is initiatized and the server starts listening to commands
  • A status message is send to the client that the server is running.
  • The service starts running the defined jobs.
  • It uses a clock(ClockBase) to make sure it checks the osc message queue periodically and starts the jobs when supposed to.


The SyncJob class is basically just a data holder. When a job is to be run, it is sent to the static execute()-function to provide information on what should be done, there it is execute. However, there are callbacks to the service to provide the client app with status and progress information.

If the app it running during a sync, the file currently being worked on is displayed in the last page.

Personal tools