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.
Test Failed
Push — master ( 8fa80d...f4cf2c )
by dup
01:36
created

versions.caches.FileCache._read_cache_file()   A

Complexity

Conditions 3

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nop 1
dl 0
loc 14
rs 10
c 0
b 0
f 0
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
import codecs
25
import os
26
import common
27
28
29
__author__ = "Olivier Delhomme <[email protected]>"
30
31
32
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
    cache_file = codecs.open(filename, 'w', encoding='utf-8')
39
    cache_file.truncate(0)
40
    cache_file.flush()
41
42
    return cache_file
43
44
# End of open_and_truncate_file() function
45
46
47
class FileCache:
48
    """
49
    This class should help in managing cache files
50
    """
51
52
    cache_filename = ''
53
    cache_dict = {}  # Dictionary of projects and their associated version
54
55
    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
        self.cache_filename = os.path.join(local_dir, filename)
62
        self.cache_dict = {}
63
        self._read_cache_file()
64
65
    # End of __init__() function
66
67
68
    def _return_project_and_version_from_line(self, line):
69
        """
70
        Splits the line into a project and a version if possible (the line
71
        must contain a whitespace).
72
        """
73
74
        line = line.strip()
75
76
        project = line
77
        version = ''
78
79
        if line.count(' ') > 0:
80
            (project, version) = line.split(' ', 1)
81
82
        return (project, version)
83
84
    # End of _return_project_and_version_from_line() function
85
86
87
    def _read_cache_file(self):
88
        """
89
        Reads the cache file and puts it into a dictionary of project with
90
        their associated version
91
        """
92
93
        if os.path.isfile(self.cache_filename):
94
            cache_file = codecs.open(self.cache_filename, 'r', encoding='utf-8')
95
96
            for line in cache_file:
97
                (project, version) = self._return_project_and_version_from_line(line)
98
                self.cache_dict[project] = version
99
100
            cache_file.close()
101
102
    # End of _read_cache_file() function
103
104
105
    def write_cache_file(self):
106
        """
107
        Owerwrites dictionary cache to the cache file
108
        """
109
110
        cache_file = open_and_truncate_file(self.cache_filename)
111
112
        for (project, version) in self.cache_dict.items():
113
            cache_file.write('%s %s\n' % (project, version))
114
115
        cache_file.close()
116
117
    # End of write_cache_file() function
118
119
    def print_if_newest_version(self, project, version, debug):
120
        """
121
        Prints the project and it's version if it is newer than the
122
        one in cache.
123
        """
124
        try:
125
            version_cache = self.cache_dict[project]
126
            common.print_debug(debug, u'\t\tIn cache: {}'.format(version_cache))
127
128
            if version != version_cache:
129
                common.print_project_version(project, version)
130
131
        except KeyError:
132
            common.print_project_version(project, version)
133
134
    # End of print_if_newest_version() function.
135
136
137
    def update_cache_dict(self, project, version, debug):
138
        """
139
        Updates cache dictionary if needed. We always keep the latest version.
140
        """
141
142
        try:
143
            version_cache = self.cache_dict[project]
144
            common.print_debug(debug, u'\t\tUpdating cache with in cache: {} / new ? version {}'.format(version_cache, version))
145
146
            if version != version_cache:
147
                self.cache_dict[project] = version
148
149
        except KeyError:
150
            self.cache_dict[project] = version
151
152
    # End of update_cache_dict() function
153
154
155
    def print_cache_dict(self, sitename):
156
        """
157
        Pretty prints the cache dictionary as it is recorded in the files.
158
        """
159
160
        print(u'{}:'.format(sitename))
161
162
        # Gets project and version tuple sorted by project lowered while sorting
163
        for project, version in sorted(self.cache_dict.items(), key=lambda proj: proj[0].lower()):
164
            print(u'\t{} {}'.format(project, version))
165
166
        print('')
167
168
    # End of print_cache_dict() function
169
# End of FileCache class
170
171
172
class FeedCache:
173
174
    cache_filename = ''
175
    year = 2016
176
    month = 5
177
    day = 1
178
    hour = 0
179
    minute = 0
180
    date_minutes = 0
181
182
183
    def __init__(self, local_dir, filename):
184
        """
185
        Inits the class. 'local_dir' must be a directory where we want to
186
        store the cache file named 'filename'
187
        """
188
189
        self.cache_filename = os.path.join(local_dir, filename)
190
        self.read_cache_feed()
191
192
    # End of __init__() function
193
194
195
    def read_cache_feed(self):
196
        """
197
        Reads the cache file which should only contain one date on the
198
        first line
199
        """
200
201
        if os.path.isfile(self.cache_filename):
202
            cache_file = codecs.open(self.cache_filename, 'r', encoding='utf-8')
203
            (self.year, self.month, self.day, self.hour, self.minute) = cache_file.readline().strip().split(' ', 4)
204
            self.date_minutes = self._calculate_minutes(int(self.year), int(self.month), int(self.day), int(self.hour), int(self.minute))
205
            cache_file.close()
206
207
    # End of read_cache_feed() function
208
209
210
    def write_cache_feed(self):
211
        """
212
        Overwrites the cache file with values stored in this class
213
        """
214
        cache_file = open_and_truncate_file(self.cache_filename)
215
216
        cache_file.write('%s %s %s %s %s' % (self.year, self.month, self.day, self.hour, self.minute))
217
218
        cache_file.close()
219
220
    # End of write_cache_feed() function
221
222
223
    def update_cache_feed(self, date):
224
        """
225
        Updates the values stored in the class with the date which should
226
        be a time.struct_time
227
        """
228
229
        self.year = date.tm_year
230
        self.month = date.tm_mon
231
        self.day = date.tm_mday
232
        self.hour = date.tm_hour
233
        self.minute = date.tm_min
234
        self.date_minutes = self._calculate_minutes_from_date(date)
235
236
    # End of update_cache_feed() function
237
238
239
    def _calculate_minutes(self, year, mon, day, hour, mins):
240
        """
241
        Calculate a number of minutes with all parameters and returns
242
        this.
243
        >>> fc = FeedCache('localdir','filename')
244
        >>> fc._calculate_minutes(2016, 5, 1, 0, 0)
245
        1059827040
246
        """
247
248
        minutes = (year * 365 * 24 * 60) + \
249
                  (mon * 30 * 24 * 60) + \
250
                  (day * 24 * 60) + \
251
                  (hour * 60) + \
252
                  (mins)
253
254
        return minutes
255
256
    # End of _calculate_minutes() function
257
258
259
    def _calculate_minutes_from_date(self, date):
260
        """
261
        Transforms a date in a number of minutes to ease comparisons
262
        and returns this number of minutes
263
        """
264
265
        return self._calculate_minutes(date.tm_year, date.tm_mon, date.tm_mday, date.tm_hour, date.tm_min)
266
267
    # End of _calculate_minutes() function
268
269
270
    def is_newer(self, date):
271
        """
272
        Tells wether "date" is newer than the one in the cache (returns True
273
        or not (returns False)
274
        """
275
276
        minutes = self._calculate_minutes_from_date(date)
277
278
        if minutes > self.date_minutes:
279
            return True
280
281
        else:
282
            return False
283
284
    # End of is_newer() function
285
# End of FeedCache class
286
287
288
def print_versions_from_cache(local_dir, cache_filename_list):
289
    """
290
    Prints all projects and their associated data from the cache
291
    """
292
    for cache_filename in cache_filename_list:
293
        site_cache = FileCache(local_dir, cache_filename)
294
        site_cache.print_cache_dict(cache_filename)
295
296
# End of print_versions_from_cache()
297