updater4pyi.upd_source module

This module defines how Updater4Pyi accesses sources, i.e. how information about the software updates are queried.

The base class is UpdateSource. Check out the github.com releases source UpdateGithubRelasesSource. For testing, you may want to try out UpdateLocalDirectorySource.

Information about individual releases are provided as BinReleaseInfo objects.

Some sources allow to determine information about releases from the file name. The class ReleaseInfoFromNameStrategy is provided for this purpose.

class updater4pyi.upd_source.BinReleaseInfo(version=None, filename=None, url=None, reltype=0, platform=None, **kwargs)[source]

Bases: object

A description of a release. This includes the release type (executable, archive, archived Mac OS X bundle), the URL at which it can be downloaded, the platform, the version etc.

Update Sources (see UpdateSource) return BinReleaseInfo objects to describe available releases. You may even reimplement this class if you need specific needs for determining release information. Note that within Updater4Pyi internals, all standard fields (version, filename, url, reltype and platform) are always queried using the accessor functions (get_version(), get_filename(), get_url(), etc.), so you could even determine that information dynamically if you really wanted to do complicated things.

You may also want to check out ReleaseInfoFromNameStrategy for automatically determining release information from the file name. It’s also highly customizable.

Arbitrary information about the release may be stored in this class, too.

get_filename()[source]

Return the filename set in the constructor.

get_platform()[source]

Return the platform set in the constructor.

get_reltype()[source]

Return the reltype set in the constructor.

get_url()[source]

Return the url set in the constructor.

get_version()[source]

Return the version set in the constructor.

class updater4pyi.upd_source.IgnoreArgument[source]
class updater4pyi.upd_source.ReleaseInfoFromNameStrategy(patterns, *args, **kwargs)[source]

Bases: object

Base class for a strategy to identify release details from a file name.

The information about a specific release (as a BinReleaseInfo object) can be obtained by calling get_release_info() with a filename and any additional information to include in the BinReleaseInfo object.

Some sources need such a stategy, such as UpdateLocalDirectorySource and UpdateGithubRelasesSource.

The patterns (see constructor) should be a list (or tuple) of patterns and rules constructed with relpattern(). The patterns are tested in the given order until a match is found. See relpattern() on information how to construct these rules.

Actually, each pattern (see return value of relpattern()) is a 2-element tuple (regexpattern, callable). The regexpattern may be a precompiled regex object (i.e. with re.compile), or it may be a string, in which case it is compiled with the re.IGNOREFLAGS set. The callable is any python callable should have the signature callable(m, filename, url, **kwargs) accepting a regexp match object, the file name, the URL at which the release can be accessed, and any keyword arguments that should be passed to the BinReleaseInfo constructor. The callable should return a new BinReleaseInfo instance.

get_release_info(filename, url, **kwargs)[source]

Return a BinReleaseInfo instance from information extracted from the filename (and possibly further information provided by url and keyword arguments).

Additional arguments are passed to the BinReleaseInfo constructor untouched. Patterns may refer to these additional fields to help identify the release information.

The list of patterns (see constructor) are tested in order until a match is found. At that point, the release information is compiled and returned.

If none of the patterns matched, then None is returned.

class updater4pyi.upd_source.UpdateGithubReleasesSource(github_user_repo, naming_strategy=None, *args, **kwargs)[source]

Bases: updater4pyi.upd_source.UpdateSource

Updates will be searched for in as releases of a github repo.

get_releases(newer_than_version=None, **kwargs)[source]

Reimplemented from UpdateSource.get_releases().

The information is retrieved using the github API, for example at https://api.github.com/repos/phfaist/bibolamazi/releases. This returns a JSON dictionary with information on the various releases. Each release has fields and a list of assets. (See Github API Documentation.)

Additional information such as the github release label is provided in each BinReleaseInfo instance:

rel_name             = the 'name' field of the release JSON dictionary
relfile_label        = the 'label' field of the release JSON dictionary
rel_description      = the 'body' field of the release JSON dictionary
rel_tag_name         = the 'tag_name' field of the release JSON dictionary
rel_html_url         = the 'html_url' field of the release JSON dictionary
relfile_content_type = the 'content_type' field of the asset JSON dictionary
class updater4pyi.upd_source.UpdateLocalDirectorySource(source_directory, naming_strategy=None, *args, **kwargs)[source]

Bases: updater4pyi.upd_source.UpdateSource

Updates will be searched for in a local directory. Useful for debugging.

Will check in the given source_directory directory for updates. Files should be organized in subdirectories which should be version names, e.g.:

1.0/
  binary-macosx[.zip]
  binary-linux[.zip]
  binary-win[.exe|.zip]
1.1/
  binary-macosx[.zip]
  binary-linux[.zip]
  binary-win[.exe|.zip]
...

This updater source is mostly for debugging purposes. There’s no real-life utility I can see...

get_releases(newer_than_version=None, **kwargs)[source]
class updater4pyi.upd_source.UpdateSource(*args, **kwargs)[source]

Bases: object

Base abstract class for an update source.

An update source takes care of accessing a e.g. repository or online server, and querying for available updates. It should be capable of returning information about available releases in the form of BinReleaseInfo objects.

Subclasses should reimplement the main function get_releases().

add_release_filter(filt)[source]

Adds a release filter to ignore some releases.

filt must be a callable which takes a positional argument, the release information object (BinReleaseInfo object). It should return True for keeping the release or False for ignoring it.

This could be, for example, to ignore beta releases.

It is the responsibility of the subclass to test release filters, for example using the test_release_filters() helper function.

get_releases(newer_than_version=None, **kwargs)[source]

Should return a list of BinReleaseInfo describing available releases. If newer_than_version argument is provided, then this function should ignore releases older or equal to the given argument. (Check out util.parse_version() to parse and compare versions.)

Note that for filters to work, the subclass must explicitly test each candidate release with test_release_filters(), and ignore the release if that function returns False.

This function should return None if no release information could be obtained (e.g. not connected to the internet). This function should return an empty list if no new updates are available.

test_release_filters(relinfo)[source]

Returns True if relinfo should be included in the releases given the installed filters, otherwise False. Note that the platform and the version selection are not implemented by filters. Filters are meant to choose between different editions, or to filter out/include beta unstable releases.

It is the responsibility of the subclass to test release filters for example with this function.

class updater4pyi.upd_source.UpdateSourceDevelopmentReleasesFilter(include_devel_releases=False, regexname=None)[source]

Bases: object

Simple filter for including/not including developemnt releases.

You can specify a class instance to UpdateSource.add_release_filter().

includeDevelReleases()[source]
setIncludeDevelReleases(include)[source]
updater4pyi.upd_source.relpattern(re_pattern, reltype=0, platform=None, **kwargs)[source]

Construct a rule to set release information depending on filename and further attributes.

The rule applies to all releases whose filename matches the given regex pattern re_pattern. The latter should be either a precompiled regexp pattern (with re.compile) or given as a string.

All further arguments specify which rules to apply to set attributes for this release information.

The release information attribute rules are applied as follows:

  1. the rules given as additional keyword arguments to relpattern are processed;
  2. the values for filename and url given to get_release_info() are set;
  3. the rules for platform and reltype given to this function are processed;
  4. the values given as additional keyword arguments to get_release_info() are set.

(Not sure why I can justify this order here, but I’m afraid of changing it.)

A rule for setting an attribute may be one of the following:

  • a fixed value: the fixed value is set to that attribute

  • a python callable: the callable is called (no, you don’t say?) and its return value is used as the value of the attribute. If the callable returned IgnoreArgument, then the rule is ignored (no one would have guessed). The callable may accept any combination of the following keyword arguments:

    • ‘m’ is the regex match object form the regex that matched the filename, and may be used to extract groups for example;
    • ‘d’ is a dictionary of values passed as additional keyword arguments to get_release_info();
    • ‘x’ is the dictionary of attributes constructed so far (by the given values and rules being processed).

The following pattern will test for a filename of the form ‘filename-VERSION-PLATFORM.EXTENSION’, ‘filename-VERSION.EXTENSION’, ‘filename-PLATFORM.EXTENSION’ or ‘filename.EXTENSION’. The information corresponding to VERSION and PLATFORM are set if they were found in the filename, otherwise we assume they’ll be figured out by some other means. The release type (reltype) is guessed depending on the extension of the filename and the platform. The example is:

pattern1 = relpattern(
    r'(-(?P<version>\d+[\w.]+))?(-(?P<platform>macosx|linux|win))?\.(?P<ext>[a-zA-Z]+)$',
    version=lambda m: m.group('version') if m.group('version') else IgnoreArgument,
    platform=lambda m: m.group('platform') if m.group('platform') else IgnoreArgument,
    reltype=lambda m, x: guess_reltype(m, x)
    )

...

def guess_reltype(m, x):
    ext = m.group('ext').lower()
    if ext == 'zip' and x.get('platform', '') == 'macosx':
        return RELTYPE_BUNDLE_ARCHIVE
    if ext in ('exe', 'bin', 'run'):
        return RELTYPE_EXE
    if ext in ('zip', 'tgz'):
        return RELTYPE_ARCHIVE
    return IgnoreArgument