versions.py (versions-1.5.0) | : | versions.py (versions-1.5.1) | ||
---|---|---|---|---|
skipping to change at line 12 | skipping to change at line 12 | |||
# -*- coding: utf8 -*- | # -*- coding: utf8 -*- | |||
# | # | |||
# versions.py : checks releases and versions of programs through RSS | # versions.py : checks releases and versions of programs through RSS | |||
# or Atom feeds and tells you | # or Atom feeds and tells you | |||
# | # | |||
# (C) Copyright 2016 - 2018 Olivier Delhomme | # (C) Copyright 2016 - 2018 Olivier Delhomme | |||
# e-mail : olivier.delhomme@free.fr | # e-mail : olivier.delhomme@free.fr | |||
# | # | |||
# This program is free software; you can redistribute it and/or modify | # This program is free software; you can redistribute it and/or modify | |||
# it under the terms of the GNU General Public License as published by | # it under the terms of the GNU General Public License as published by | |||
# the Free Software Foundation; either version 2, or (at your option) | # the Free Software Foundation; either version 3, or (at your option) | |||
# any later version. | # any later version. | |||
# | # | |||
# This program is distributed in the hope that it will be useful, | # This program is distributed in the hope that it will be useful, | |||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
# GNU General Public License for more details. | # GNU General Public License for more details. | |||
# | # | |||
# You should have received a copy of the GNU General Public License | # You should have received a copy of the GNU General Public License | |||
# along with this program; if not, write to the Free Software Foundation, | # along with this program; if not, write to the Free Software Foundation, | |||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
skipping to change at line 38 | skipping to change at line 38 | |||
import os | import os | |||
import re | import re | |||
import errno | import errno | |||
import time | import time | |||
import doctest | import doctest | |||
import feedparser | import feedparser | |||
import yaml | import yaml | |||
import operator | import operator | |||
__author__ = "Olivier Delhomme <olivier.delhomme@free.fr>" | __author__ = "Olivier Delhomme <olivier.delhomme@free.fr>" | |||
__date__ = "04.05.2018" | __date__ = "22.05.2018" | |||
__version__ = "1.5.0" | __version__ = "1.5.1" | |||
""" | """ | |||
This program checks projects versions through RSS and Atom feeds and | This program checks projects versions through RSS and Atom feeds and | |||
should only print those with new release version. | should only print those with new release version. | |||
It implements checking for projects in github.com and freshcode.club. | It implements checking for projects in github.com and freshcode.club. | |||
Projects must be added to a YAML file (named by default | Projects must be added to a YAML file (named by default | |||
~/.config/versions/versions.yaml). One can use --file=FILENAME option | ~/.config/versions/versions.yaml). One can use --file=FILENAME option | |||
to specify an alternative YAML file. version.yaml is included as an | to specify an alternative YAML file. version.yaml is included as an | |||
example in this project. | example in this project. | |||
skipping to change at line 205 | skipping to change at line 205 | |||
def extract_project_url(self, site_name): | def extract_project_url(self, site_name): | |||
""" | """ | |||
Extracts the url definition where to check project version. | Extracts the url definition where to check project version. | |||
""" | """ | |||
return self.extract_variable_from_site(site_name, 'url', '') | return self.extract_variable_from_site(site_name, 'url', '') | |||
# End of extract_project_url() function | # End of extract_project_url() function | |||
def extract_project_entry(self, site_name): | ||||
""" | ||||
Extracts the entry definition (if any) of a site. | ||||
""" | ||||
return self.extract_variable_from_site(site_name, 'entry', '') | ||||
# End of extract_project_entry() function. | ||||
def is_site_of_type(self, site_name, site_type): | def is_site_of_type(self, site_name, site_type): | |||
""" | """ | |||
Returns True if site_name is of type 'site_type' | Returns True if site_name is of type 'site_type' | |||
""" | """ | |||
site_definition = self.extract_site_definition(site_name) | site_definition = self.extract_site_definition(site_name) | |||
if 'type' in site_definition: | if 'type' in site_definition: | |||
return (site_definition['type'] == site_type) | return (site_definition['type'] == site_type) | |||
else: | else: | |||
return False | return False | |||
skipping to change at line 279 | skipping to change at line 288 | |||
def check_versions(self): | def check_versions(self): | |||
""" | """ | |||
Checks versions by parsing online feeds. | Checks versions by parsing online feeds. | |||
""" | """ | |||
# Checks projects from by project sites such as github and sourceforge | # Checks projects from by project sites such as github and sourceforge | |||
byproject_site_list = self.extract_site_list('byproject') | byproject_site_list = self.extract_site_list('byproject') | |||
for site_name in byproject_site_list: | for site_name in byproject_site_list: | |||
print_debug(self.options.debug, u'Checking {} projects'.format(site_ name)) | print_debug(self.options.debug, u'Checking {} projects'.format(site_ name)) | |||
(project_list, project_url, cache_filename) = self.get_infos_for_sit e(site_name) | (project_list, project_url, cache_filename, project_entry) = self.ge t_infos_for_site(site_name) | |||
feed_filename = u'{}.feed'.format(site_name) | feed_filename = u'{}.feed'.format(site_name) | |||
check_versions_feeds_by_projects(project_list, self.local_dir, self. options.debug, project_url, cache_filename, feed_filename) | check_versions_feeds_by_projects(project_list, self.local_dir, self. options.debug, project_url, cache_filename, feed_filename, project_entry) | |||
# Checks projects from 'list' tupe sites such as freshcode.club | # Checks projects from 'list' tupe sites such as freshcode.club | |||
list_site_list = self.extract_site_list('list') | list_site_list = self.extract_site_list('list') | |||
for site_name in list_site_list: | for site_name in list_site_list: | |||
print_debug(self.options.debug, u'Checking {} updates'.format(site_n ame)) | print_debug(self.options.debug, u'Checking {} updates'.format(site_n ame)) | |||
(project_list, project_url, cache_filename) = self.get_infos_for_sit e(site_name) | (project_list, project_url, cache_filename, project_entry) = self.ge t_infos_for_site(site_name) | |||
regex = self.extract_regex_from_site(site_name) | regex = self.extract_regex_from_site(site_name) | |||
multiproject = self.extract_multiproject_from_site(site_name) | multiproject = self.extract_multiproject_from_site(site_name) | |||
feed_filename = u'{}.feed'.format(site_name) | feed_filename = u'{}.feed'.format(site_name) | |||
check_versions_for_list_sites(project_list, project_url, cache_filen ame, feed_filename, self.local_dir, self.options.debug, regex, multiproject) | check_versions_for_list_sites(project_list, project_url, cache_filen ame, feed_filename, self.local_dir, self.options.debug, regex, multiproject) | |||
# End of check_versions() function | # End of check_versions() function | |||
def get_infos_for_site(self, site_name): | def get_infos_for_site(self, site_name): | |||
""" | """ | |||
Returns informations about a site as a tuple | Returns informations about a site as a tuple | |||
(list of projects, url to check, filename of the cache) | (list of projects, url to check, filename of the cache) | |||
""" | """ | |||
project_list = self.extract_project_list_from_site(site_name) | project_list = self.extract_project_list_from_site(site_name) | |||
project_url = self.extract_project_url(site_name) | project_url = self.extract_project_url(site_name) | |||
project_entry = self.extract_project_entry(site_name) | ||||
cache_filename = u'{}.cache'.format(site_name) | cache_filename = u'{}.cache'.format(site_name) | |||
return (project_list, project_url, cache_filename) | return (project_list, project_url, cache_filename, project_entry) | |||
# End of get_infos_for_site() function | # End of get_infos_for_site() function | |||
# End of Conf class | # End of Conf class | |||
class FileCache: | class FileCache: | |||
""" | """ | |||
This class should help in managing cache files | This class should help in managing cache files | |||
""" | """ | |||
skipping to change at line 674 | skipping to change at line 684 | |||
published_date = get_entry_published_date(feed_list[0]) | published_date = get_entry_published_date(feed_list[0]) | |||
feed_info.update_cache_feed(published_date) | feed_info.update_cache_feed(published_date) | |||
feed_info.write_cache_feed() | feed_info.write_cache_feed() | |||
else: | else: | |||
feed_list.insert(0, feed.entries[0]) | feed_list.insert(0, feed.entries[0]) | |||
return feed_list | return feed_list | |||
def get_latest_release_by_title(project, debug, feed_url, local_dir, feed_filena me): | def get_latest_release_by_title(project, debug, feed_url, local_dir, feed_filena me, project_entry): | |||
""" | """ | |||
Gets the latest release or the releases between the last checked time of | Gets the latest release or the releases between the last checked time of | |||
a program on a site of type 'byproject'. | a program on a site of type 'byproject'. | |||
project must be a string that represents the project (user/repository in | project must be a string that represents the project (user/repository in | |||
github for instance). | github for instance). | |||
Returns a tuple which contains the name of the project, a list of versions | Returns a tuple which contains the name of the project, a list of versions | |||
and a boolean that indicates if we checked by last checked time (True) or | and a boolean that indicates if we checked by last checked time (True) or | |||
by release (False). | by release (False). | |||
""" | """ | |||
feed_list = [] | feed_list = [] | |||
(valued, name, regex, entry) = get_values_from_project(project) | (valued, name, regex, entry) = get_values_from_project(project) | |||
last_checked = is_entry_last_checked(entry) | ||||
if is_entry_last_checked(project_entry): | ||||
last_checked = True | ||||
entry = project_entry | ||||
else: | ||||
last_checked = is_entry_last_checked(entry) | ||||
filename = format_project_feed_filename(feed_filename, name) | filename = format_project_feed_filename(feed_filename, name) | |||
url = feed_url.format(name) | url = feed_url.format(name) | |||
feed = get_feed_entries_from_url(url) | feed = get_feed_entries_from_url(url) | |||
if feed is not None and len(feed.entries) > 0: | if feed is not None and len(feed.entries) > 0: | |||
feed_list = get_releases_filtering_feed(debug, local_dir, filename, feed , entry) | feed_list = get_releases_filtering_feed(debug, local_dir, filename, feed , entry) | |||
if valued and regex != '': | if valued and regex != '': | |||
# Here we match the whole list against the regex and replace the | # Here we match the whole list against the regex and replace the | |||
# title's entry of the result of that match upon success. | # title's entry of the result of that match upon success. | |||
for entry in feed_list: | for entry in feed_list: | |||
res = re.match(regex, entry.title) | res = re.match(regex, entry.title) | |||
# Here we should make a new list with the matched entries and le ave tho other ones | ||||
if res: | if res: | |||
entry.title = res.group(1) | entry.title = res.group(1) | |||
print_debug(debug, u'\tname: {}\n\tversion: {}\n\tregex: {} : {} '.format(name, entry.title, regex, res)) | print_debug(debug, u'\tname: {}\n\tversion: {}\n\tregex: {} : {} '.format(name, entry.title, regex, res)) | |||
print_debug(debug, u'\tProject {}: {}'.format(name, entry.title)) | print_debug(debug, u'\tProject {}: {}'.format(name, entry.title)) | |||
return (name, feed_list, last_checked) | return (name, feed_list, last_checked) | |||
# End of get_latest_release_by_title() function | # End of get_latest_release_by_title() function | |||
def print_project_version(project, version): | def print_project_version(project, version): | |||
""" | """ | |||
Prints to the standard output project name and it's version. | Prints to the standard output project name and it's version. | |||
""" | """ | |||
print(u'{} {}'.format(project, version)) | print(u'{} {}'.format(project, version)) | |||
# End of print_project_version() function | # End of print_project_version() function | |||
def check_versions_feeds_by_projects(project_list, local_dir, debug, feed_url, c ache_filename, feed_filename): | def check_versions_feeds_by_projects(project_list, local_dir, debug, feed_url, c ache_filename, feed_filename, project_entry): | |||
""" | """ | |||
Checks project's versions on feed_url if any are defined in the yaml | Checks project's versions on feed_url if any are defined in the yaml | |||
file under the specified tag that got the project_list passed as an argument . | file under the specified tag that got the project_list passed as an argument . | |||
""" | """ | |||
site_cache = FileCache(local_dir, cache_filename) | site_cache = FileCache(local_dir, cache_filename) | |||
for project in project_list: | for project in project_list: | |||
(name, feed_list, last_checked) = get_latest_release_by_title(project, d ebug, feed_url, local_dir, feed_filename) | (name, feed_list, last_checked) = get_latest_release_by_title(project, d ebug, feed_url, local_dir, feed_filename, project_entry) | |||
if len(feed_list) >= 1: | if len(feed_list) >= 1: | |||
# Updating the cache with the latest version (the first entry) | # Updating the cache with the latest version (the first entry) | |||
version = feed_list[0].title | version = feed_list[0].title | |||
if not last_checked: | if not last_checked: | |||
# printing only for latest release as last checked is | # printing only for latest release as last checked is | |||
# already filtered and to be printed entirely | # already filtered and to be printed entirely | |||
site_cache.print_if_newest_version(name, version, debug) | site_cache.print_if_newest_version(name, version, debug) | |||
End of changes. 13 change blocks. | ||||
11 lines changed or deleted | 27 lines changed or added |