@@ -0,0 +1,2598 @@
+# !/usr/bin/python3%0A# coding: utf-8%0A%0A# Copyright 2016-2018 Stefano Fogarollo%0A#%0A# Licensed under the Apache License, Version 2.0 (the %22License%22);%0A# you may not use this file except in compliance with the License.%0A# You may obtain a copy of the License at%0A#%0A# http://www.apache.org/licenses/LICENSE-2.0%0A#%0A# Unless required by applicable law or agreed to in writing, software%0A# distributed under the License is distributed on an %22AS IS%22 BASIS,%0A# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.%0A# See the License for the specific language governing permissions and%0A# limitations under the License.%0A%0A%0A%22%22%22 Cron-ify python apps with simple config files %22%22%22%0A%0Aimport datetime%0Aimport json%0A%0A%0Aclass AppCronLock(object):%0A    %22%22%22 Checks if app can proceed; generates lock %22%22%22%0A%0A    DATETIME_FORMAT = %22%25Y-%25m-%25d %25H:%25M:%25S%22%0A%0A    def __init__(self, lock_file):%0A        %22%22%22%0A        :param lock_file: str%0A            Path to lock file%0A        %22%22%22%0A%0A        object.__init__(self)%0A        self.lock_file = lock_file%0A        self.update_interval = 7%0A        self.last_update = datetime.datetime.fromtimestamp(0)%0A        self.data = None%0A        self.parse_lock()%0A%0A    def set_update_interval(self, days=7):%0A        %22%22%22%0A        :param days: int%0A            Days between 2 consecutive app updates%0A        :return: void%0A            Sets app interval update%0A        %22%22%22%0A%0A        self.update_interval = days%0A%0A    def can_proceed(self):%0A        %22%22%22%0A        :return: bool%0A            True iff app is not locked and time since last update %3C app%0A            update interval%0A        %22%22%22%0A%0A        now = datetime.datetime.now()%0A        return now %3E= self.last_update + %5C%0A                      datetime.timedelta(days=self.update_interval)%0A%0A    def parse_lock(self):%0A        %22%22%22%0A        :return: %7B%7D%0A            Details about last update%0A        %22%22%22%0A%0A        try:%0A            with open(self.lock_file, %22r%22) as reader:%0A                data = json.loads(reader.read())%0A                self.last_update = datetime.datetime.strptime(%0A                    data%5B%22last_update%22%5D,%0A                    AppCronLock.DATETIME_FORMAT%0A                )%0A        except:  # malformed lock file%0A            self.write_lock(last_update=datetime.datetime.fromtimestamp(0))%0A            self.parse_lock()%0A%0A    def write_lock(self, last_update=datetime.datetime.now()):%0A        %22%22%22%0A        :return: void%0A            Writes lock file%0A        %22%22%22%0A%0A        data = %7B%0A            %22last_update%22: last_update.strftime(AppCronLock.DATETIME_FORMAT)%0A        %7D%0A%0A        with open(self.lock_file, %22w%22) as writer:%0A            json.dump(data, writer)%0A

add AppCronLock class