GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

versions.caches   A
last analyzed

Complexity

Total Complexity 29

Size/Duplication

Total Lines 283
Duplicated Lines 0 %

Test Coverage

Coverage 88.78%

Importance

Changes 0
Metric Value
wmc 29
eloc 104
dl 0
loc 283
ccs 87
cts 98
cp 0.8878
rs 10
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A FileCache.__init__() 0 9 1
A FeedCache._calculate_minutes_from_date() 0 7 1
A FileCache._read_cache_file() 0 14 3
A FeedCache.read_cache_feed() 0 11 2
A FileCache.print_cache_dict() 0 12 3
A FileCache.update_cache_dict() 0 14 3
A FeedCache._calculate_minutes() 0 16 1
A FileCache.write_cache_file() 0 11 2
A FileCache.print_if_newest_version() 0 14 3
A FeedCache.update_cache_feed() 0 12 1
A FileCache._return_project_and_version_from_line() 0 15 2
A FeedCache.__init__() 0 8 1
A FeedCache.is_newer() 0 13 2
A FeedCache.write_cache_feed() 0 9 1

2 Functions

Rating   Name   Duplication   Size   Complexity  
A open_and_truncate_file() 0 11 1
A print_versions_from_cache() 0 7 2
1
#!/usr/bin/env python
2
# -*- coding: utf8 -*-
3
#
4
#  caches.py : module that provides a class and tools to manage caches
5
#              for versions.py modules
6
#
7
#  (C) Copyright 2016 - 2018 Olivier Delhomme
8
#  e-mail : [email protected]
9
#
10
#  This program is free software; you can redistribute it and/or modify
11
#  it under the terms of the GNU General Public License as published by
12
#  the Free Software Foundation; either version 3, or (at your option)
13
#  any later version.
14
#
15
#  This program is distributed in the hope that it will be useful,
16
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
#  GNU General Public License for more details.
19
#
20
#  You should have received a copy of the GNU General Public License
21
#  along with this program; if not, write to the Free Software Foundation,
22
#  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 1
import codecs
25 1
import os
26 1
import common
27
28
29 1
__author__ = "Olivier Delhomme <[email protected]>"
30
31
32 1
def open_and_truncate_file(filename):
33
    """
34
    Opens filename for writing truncating it to a zero length file
35
    and returns a python file object.
36
    """
37
38 1
    cache_file = codecs.open(filename, 'w', encoding='utf-8')
39 1
    cache_file.truncate(0)
40 1
    cache_file.flush()
41
42 1
    return cache_file
43
44
# End of open_and_truncate_file() function
45
46
47 1
class FileCache:
48
    """
49
    This class should help in managing cache files
50
    """
51
52 1
    cache_filename = ''
53 1
    cache_dict = {}  # Dictionary of projects and their associated version
54
55 1
    def __init__(self, local_dir, filename):
56
        """
57
        Inits the class. 'local_dir' must be a directory where we want to
58
        store the cache file named 'filename'
59
        """
60
61 1
        self.cache_filename = os.path.join(local_dir, filename)
62 1
        self.cache_dict = {}
63 1
        self._read_cache_file()
64
65
    # End of __init__() function
66
67 1
    def _return_project_and_version_from_line(self, line):
68
        """
69
        Splits the line into a project and a version if possible (the line
70
        must contain a whitespace).
71
        """
72
73 1
        line = line.strip()
74
75 1
        project = line
76 1
        version = ''
77
78 1
        if line.count(' ') > 0:
79 1
            (project, version) = line.split(' ', 1)
80
81 1
        return (project, version)
82
83
    # End of _return_project_and_version_from_line() function
84
85 1
    def _read_cache_file(self):
86
        """
87
        Reads the cache file and puts it into a dictionary of project with
88
        their associated version
89
        """
90
91 1
        if os.path.isfile(self.cache_filename):
92 1
            cache_file = codecs.open(self.cache_filename, 'r', encoding='utf-8')
93
94 1
            for line in cache_file:
95 1
                (project, version) = self._return_project_and_version_from_line(line)
96 1
                self.cache_dict[project] = version
97
98 1
            cache_file.close()
99
100
    # End of _read_cache_file() function
101
102 1
    def write_cache_file(self):
103
        """
104
        Overwrites dictionary cache to the cache file
105
        """
106
107 1
        cache_file = open_and_truncate_file(self.cache_filename)
108
109 1
        for (project, version) in self.cache_dict.items():
110 1
            cache_file.write('%s %s\n' % (project, version))
111
112 1
        cache_file.close()
113
114
    # End of write_cache_file() function
115
116 1
    def print_if_newest_version(self, project, version, debug):
117
        """
118
        Prints the project and it's version if it is newer than the
119
        one in cache.
120
        """
121 1
        try:
122 1
            version_cache = self.cache_dict[project]
123
            common.print_debug(debug, u'\t\tIn cache: {}'.format(version_cache))
124
125
            if version != version_cache:
126
                common.print_project_version(project, version)
127
128 1
        except KeyError:
129 1
            common.print_project_version(project, version)
130
131
    # End of print_if_newest_version() function.
132
133 1
    def update_cache_dict(self, project, version, debug):
134
        """
135
        Updates cache dictionary if needed. We always keep the latest version.
136
        """
137
138 1
        try:
139 1
            version_cache = self.cache_dict[project]
140
            common.print_debug(debug, u'\t\tUpdating cache with in cache: {} / new ? version {}'.format(version_cache, version))
141
142
            if version != version_cache:
143
                self.cache_dict[project] = version
144
145 1
        except KeyError:
146 1
            self.cache_dict[project] = version
147
148
    # End of update_cache_dict() function
149
150 1
    def print_cache_dict(self, sitename):
151
        """
152
        Pretty prints the cache dictionary as it is recorded in the files.
153
        """
154
155 1
        print(u'{}:'.format(sitename))
156
157
        # Gets project and version tuple sorted by project lowered while sorting
158 1
        for project, version in sorted(self.cache_dict.items(), key=lambda proj: proj[0].lower()):
159 1
            print(u'\t{} {}'.format(project, version))
160
161 1
        print('')
162
163
    # End of print_cache_dict() function
164
# End of FileCache class
165
166
167 1
class FeedCache:
168
169 1
    cache_filename = ''
170 1
    year = 2016
171 1
    month = 5
172 1
    day = 1
173 1
    hour = 0
174 1
    minute = 0
175 1
    date_minutes = 0
176
177 1
    def __init__(self, local_dir, filename):
178
        """
179
        Inits the class. 'local_dir' must be a directory where we want to
180
        store the cache file named 'filename'
181
        """
182
183 1
        self.cache_filename = os.path.join(local_dir, filename)
184 1
        self.read_cache_feed()
185
186
    # End of __init__() function
187
188 1
    def read_cache_feed(self):
189
        """
190
        Reads the cache file which should only contain one date on the
191
        first line
192
        """
193
194 1
        if os.path.isfile(self.cache_filename):
195
            cache_file = codecs.open(self.cache_filename, 'r', encoding='utf-8')
196
            (self.year, self.month, self.day, self.hour, self.minute) = cache_file.readline().strip().split(' ', 4)
197
            self.date_minutes = self._calculate_minutes(int(self.year), int(self.month), int(self.day), int(self.hour), int(self.minute))
198
            cache_file.close()
199
200
    # End of read_cache_feed() function
201
202 1
    def write_cache_feed(self):
203
        """
204
        Overwrites the cache file with values stored in this class
205
        """
206 1
        cache_file = open_and_truncate_file(self.cache_filename)
207
208 1
        cache_file.write('%s %s %s %s %s' % (self.year, self.month, self.day, self.hour, self.minute))
209
210 1
        cache_file.close()
211
212
    # End of write_cache_feed() function
213
214 1
    def update_cache_feed(self, date):
215
        """
216
        Updates the values stored in the class with the date which should
217
        be a time.struct_time
218
        """
219
220 1
        self.year = date.tm_year
221 1
        self.month = date.tm_mon
222 1
        self.day = date.tm_mday
223 1
        self.hour = date.tm_hour
224 1
        self.minute = date.tm_min
225 1
        self.date_minutes = self._calculate_minutes_from_date(date)
226
227
    # End of update_cache_feed() function
228
229 1
    def _calculate_minutes(self, year, mon, day, hour, mins):
230
        """
231
        Calculate a number of minutes with all parameters and returns
232
        this.
233
        >>> fc = FeedCache('localdir','filename')
234
        >>> fc._calculate_minutes(2016, 5, 1, 0, 0)
235
        1059827040
236
        """
237
238 1
        minutes = (year * 365 * 24 * 60) + \
239
                  (mon * 30 * 24 * 60) + \
240
                  (day * 24 * 60) + \
241
                  (hour * 60) + \
242
                  (mins)
243
244 1
        return minutes
245
246
    # End of _calculate_minutes() function
247
248 1
    def _calculate_minutes_from_date(self, date):
249
        """
250
        Transforms a date in a number of minutes to ease comparisons
251
        and returns this number of minutes
252
        """
253
254 1
        return self._calculate_minutes(date.tm_year, date.tm_mon, date.tm_mday, date.tm_hour, date.tm_min)
255
256
    # End of _calculate_minutes() function
257
258 1
    def is_newer(self, date):
259
        """
260
        Tells whether "date" is newer than the one in the cache (returns True
261
        or not (returns False)
262
        """
263
264 1
        minutes = self._calculate_minutes_from_date(date)
265
266 1
        if minutes > self.date_minutes:
267 1
            return True
268
269
        else:
270
            return False
271
272
    # End of is_newer() function
273
# End of FeedCache class
274
275
276 1
def print_versions_from_cache(local_dir, cache_filename_list):
277
    """
278
    Prints all projects and their associated data from the cache
279
    """
280 1
    for cache_filename in cache_filename_list:
281 1
        site_cache = FileCache(local_dir, cache_filename)
282 1
        site_cache.print_cache_dict(cache_filename)
283
284
# End of print_versions_from_cache()
285