mirror of
https://github.com/robweber/xbmcbackup.git
synced 2024-11-14 20:35:48 +01:00
replace relativedelta.py with one from dateutil package
This commit is contained in:
parent
6514b3db02
commit
6c99667afa
@ -3,6 +3,7 @@
|
|||||||
name="Backup" version="1.6.0~beta1" provider-name="robweber">
|
name="Backup" version="1.6.0~beta1" provider-name="robweber">
|
||||||
<requires>
|
<requires>
|
||||||
<import addon="xbmc.python" version="3.0.0"/>
|
<import addon="xbmc.python" version="3.0.0"/>
|
||||||
|
<import addon="script.module.dateutil" version="2.8.0" />
|
||||||
<import addon="script.module.future" version="0.16.0.4"/>
|
<import addon="script.module.future" version="0.16.0.4"/>
|
||||||
<!-- for dropbox -->
|
<!-- for dropbox -->
|
||||||
<import addon="script.module.requests" version="2.18.4"/>
|
<import addon="script.module.requests" version="2.18.4"/>
|
||||||
|
@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
|||||||
### Added
|
### Added
|
||||||
|
|
||||||
- added new badges for Kodi Version, TravisCI and license information from shields.io
|
- added new badges for Kodi Version, TravisCI and license information from shields.io
|
||||||
|
- dependency on script.module.dateutil for relativedelta.py class
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
@ -24,6 +25,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
|||||||
- removed need for urlparse library
|
- removed need for urlparse library
|
||||||
- Removed GoogleDrive support - issues with python 3 compatibility
|
- Removed GoogleDrive support - issues with python 3 compatibility
|
||||||
- removed script.module.dropbox dependency, need version 9+ and it isn't in the Kodi repo yet
|
- removed script.module.dropbox dependency, need version 9+ and it isn't in the Kodi repo yet
|
||||||
|
- removed relativedelta.py, use the dateutil module for this
|
||||||
|
|
||||||
## [Version 1.5.2](https://github.com/robweber/xbmcbackup/compare/krypton-1.5.1...robweber:krypton-1.5.2) - 2019-09-30
|
## [Version 1.5.2](https://github.com/robweber/xbmcbackup/compare/krypton-1.5.1...robweber:krypton-1.5.2) - 2019-09-30
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
from time import time, mktime
|
from time import time, mktime
|
||||||
from datetime import datetime, date
|
from datetime import datetime
|
||||||
from .relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
|
|
||||||
search_re = re.compile(r'^([^-]+)-([^-/]+)(/(.*))?$')
|
search_re = re.compile(r'^([^-]+)-([^-/]+)(/(.*))?$')
|
||||||
only_int_re = re.compile(r'^\d+$')
|
only_int_re = re.compile(r'^\d+$')
|
||||||
|
@ -1,430 +0,0 @@
|
|||||||
"""
|
|
||||||
Copyright (c) 2003-2010 Gustavo Niemeyer <gustavo@niemeyer.net>
|
|
||||||
|
|
||||||
This module offers extensions to the standard python 2.3+
|
|
||||||
datetime module.
|
|
||||||
"""
|
|
||||||
__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
|
|
||||||
__license__ = "PSF License"
|
|
||||||
|
|
||||||
import datetime
|
|
||||||
import calendar
|
|
||||||
|
|
||||||
__all__ = ["relativedelta", "MO", "TU", "WE", "TH", "FR", "SA", "SU"]
|
|
||||||
|
|
||||||
class weekday(object):
|
|
||||||
__slots__ = ["weekday", "n"]
|
|
||||||
|
|
||||||
def __init__(self, weekday, n=None):
|
|
||||||
self.weekday = weekday
|
|
||||||
self.n = n
|
|
||||||
|
|
||||||
def __call__(self, n):
|
|
||||||
if n == self.n:
|
|
||||||
return self
|
|
||||||
else:
|
|
||||||
return self.__class__(self.weekday, n)
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
|
||||||
try:
|
|
||||||
if self.weekday != other.weekday or self.n != other.n:
|
|
||||||
return False
|
|
||||||
except AttributeError:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
s = ("MO", "TU", "WE", "TH", "FR", "SA", "SU")[self.weekday]
|
|
||||||
if not self.n:
|
|
||||||
return s
|
|
||||||
else:
|
|
||||||
return "%s(%+d)" % (s, self.n)
|
|
||||||
|
|
||||||
MO, TU, WE, TH, FR, SA, SU = weekdays = tuple([weekday(x) for x in range(7)])
|
|
||||||
|
|
||||||
class relativedelta:
|
|
||||||
"""
|
|
||||||
The relativedelta type is based on the specification of the excelent
|
|
||||||
work done by M.-A. Lemburg in his mx.DateTime extension. However,
|
|
||||||
notice that this type does *NOT* implement the same algorithm as
|
|
||||||
his work. Do *NOT* expect it to behave like mx.DateTime's counterpart.
|
|
||||||
|
|
||||||
There's two different ways to build a relativedelta instance. The
|
|
||||||
first one is passing it two date/datetime classes:
|
|
||||||
|
|
||||||
relativedelta(datetime1, datetime2)
|
|
||||||
|
|
||||||
And the other way is to use the following keyword arguments:
|
|
||||||
|
|
||||||
year, month, day, hour, minute, second, microsecond:
|
|
||||||
Absolute information.
|
|
||||||
|
|
||||||
years, months, weeks, days, hours, minutes, seconds, microseconds:
|
|
||||||
Relative information, may be negative.
|
|
||||||
|
|
||||||
weekday:
|
|
||||||
One of the weekday instances (MO, TU, etc). These instances may
|
|
||||||
receive a parameter N, specifying the Nth weekday, which could
|
|
||||||
be positive or negative (like MO(+1) or MO(-2). Not specifying
|
|
||||||
it is the same as specifying +1. You can also use an integer,
|
|
||||||
where 0=MO.
|
|
||||||
|
|
||||||
leapdays:
|
|
||||||
Will add given days to the date found, if year is a leap
|
|
||||||
year, and the date found is post 28 of february.
|
|
||||||
|
|
||||||
yearday, nlyearday:
|
|
||||||
Set the yearday or the non-leap year day (jump leap days).
|
|
||||||
These are converted to day/month/leapdays information.
|
|
||||||
|
|
||||||
Here is the behavior of operations with relativedelta:
|
|
||||||
|
|
||||||
1) Calculate the absolute year, using the 'year' argument, or the
|
|
||||||
original datetime year, if the argument is not present.
|
|
||||||
|
|
||||||
2) Add the relative 'years' argument to the absolute year.
|
|
||||||
|
|
||||||
3) Do steps 1 and 2 for month/months.
|
|
||||||
|
|
||||||
4) Calculate the absolute day, using the 'day' argument, or the
|
|
||||||
original datetime day, if the argument is not present. Then,
|
|
||||||
subtract from the day until it fits in the year and month
|
|
||||||
found after their operations.
|
|
||||||
|
|
||||||
5) Add the relative 'days' argument to the absolute day. Notice
|
|
||||||
that the 'weeks' argument is multiplied by 7 and added to
|
|
||||||
'days'.
|
|
||||||
|
|
||||||
6) Do steps 1 and 2 for hour/hours, minute/minutes, second/seconds,
|
|
||||||
microsecond/microseconds.
|
|
||||||
|
|
||||||
7) If the 'weekday' argument is present, calculate the weekday,
|
|
||||||
with the given (wday, nth) tuple. wday is the index of the
|
|
||||||
weekday (0-6, 0=Mon), and nth is the number of weeks to add
|
|
||||||
forward or backward, depending on its signal. Notice that if
|
|
||||||
the calculated date is already Monday, for example, using
|
|
||||||
(0, 1) or (0, -1) won't change the day.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, dt1=None, dt2=None,
|
|
||||||
years=0, months=0, days=0, leapdays=0, weeks=0,
|
|
||||||
hours=0, minutes=0, seconds=0, microseconds=0,
|
|
||||||
year=None, month=None, day=None, weekday=None,
|
|
||||||
yearday=None, nlyearday=None,
|
|
||||||
hour=None, minute=None, second=None, microsecond=None):
|
|
||||||
if dt1 and dt2:
|
|
||||||
if not isinstance(dt1, datetime.date) or \
|
|
||||||
not isinstance(dt2, datetime.date):
|
|
||||||
raise TypeError("relativedelta only diffs datetime/date")
|
|
||||||
if type(dt1) is not type(dt2):
|
|
||||||
if not isinstance(dt1, datetime.datetime):
|
|
||||||
dt1 = datetime.datetime.fromordinal(dt1.toordinal())
|
|
||||||
elif not isinstance(dt2, datetime.datetime):
|
|
||||||
dt2 = datetime.datetime.fromordinal(dt2.toordinal())
|
|
||||||
self.years = 0
|
|
||||||
self.months = 0
|
|
||||||
self.days = 0
|
|
||||||
self.leapdays = 0
|
|
||||||
self.hours = 0
|
|
||||||
self.minutes = 0
|
|
||||||
self.seconds = 0
|
|
||||||
self.microseconds = 0
|
|
||||||
self.year = None
|
|
||||||
self.month = None
|
|
||||||
self.day = None
|
|
||||||
self.weekday = None
|
|
||||||
self.hour = None
|
|
||||||
self.minute = None
|
|
||||||
self.second = None
|
|
||||||
self.microsecond = None
|
|
||||||
self._has_time = 0
|
|
||||||
|
|
||||||
months = (dt1.year*12+dt1.month)-(dt2.year*12+dt2.month)
|
|
||||||
self._set_months(months)
|
|
||||||
dtm = self.__radd__(dt2)
|
|
||||||
if dt1 < dt2:
|
|
||||||
while dt1 > dtm:
|
|
||||||
months += 1
|
|
||||||
self._set_months(months)
|
|
||||||
dtm = self.__radd__(dt2)
|
|
||||||
else:
|
|
||||||
while dt1 < dtm:
|
|
||||||
months -= 1
|
|
||||||
self._set_months(months)
|
|
||||||
dtm = self.__radd__(dt2)
|
|
||||||
delta = dt1 - dtm
|
|
||||||
self.seconds = delta.seconds+delta.days*86400
|
|
||||||
self.microseconds = delta.microseconds
|
|
||||||
else:
|
|
||||||
self.years = years
|
|
||||||
self.months = months
|
|
||||||
self.days = days+weeks*7
|
|
||||||
self.leapdays = leapdays
|
|
||||||
self.hours = hours
|
|
||||||
self.minutes = minutes
|
|
||||||
self.seconds = seconds
|
|
||||||
self.microseconds = microseconds
|
|
||||||
self.year = year
|
|
||||||
self.month = month
|
|
||||||
self.day = day
|
|
||||||
self.hour = hour
|
|
||||||
self.minute = minute
|
|
||||||
self.second = second
|
|
||||||
self.microsecond = microsecond
|
|
||||||
|
|
||||||
if type(weekday) is int:
|
|
||||||
self.weekday = weekdays[weekday]
|
|
||||||
else:
|
|
||||||
self.weekday = weekday
|
|
||||||
|
|
||||||
yday = 0
|
|
||||||
if nlyearday:
|
|
||||||
yday = nlyearday
|
|
||||||
elif yearday:
|
|
||||||
yday = yearday
|
|
||||||
if yearday > 59:
|
|
||||||
self.leapdays = -1
|
|
||||||
if yday:
|
|
||||||
ydayidx = [31,59,90,120,151,181,212,243,273,304,334,366]
|
|
||||||
for idx, ydays in enumerate(ydayidx):
|
|
||||||
if yday <= ydays:
|
|
||||||
self.month = idx+1
|
|
||||||
if idx == 0:
|
|
||||||
self.day = yday
|
|
||||||
else:
|
|
||||||
self.day = yday-ydayidx[idx-1]
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
raise ValueError("invalid year day (%d)" % yday)
|
|
||||||
|
|
||||||
self._fix()
|
|
||||||
|
|
||||||
def _fix(self):
|
|
||||||
if abs(self.microseconds) > 999999:
|
|
||||||
s = self.microseconds//abs(self.microseconds)
|
|
||||||
div, mod = divmod(self.microseconds*s, 1000000)
|
|
||||||
self.microseconds = mod*s
|
|
||||||
self.seconds += div*s
|
|
||||||
if abs(self.seconds) > 59:
|
|
||||||
s = self.seconds//abs(self.seconds)
|
|
||||||
div, mod = divmod(self.seconds*s, 60)
|
|
||||||
self.seconds = mod*s
|
|
||||||
self.minutes += div*s
|
|
||||||
if abs(self.minutes) > 59:
|
|
||||||
s = self.minutes//abs(self.minutes)
|
|
||||||
div, mod = divmod(self.minutes*s, 60)
|
|
||||||
self.minutes = mod*s
|
|
||||||
self.hours += div*s
|
|
||||||
if abs(self.hours) > 23:
|
|
||||||
s = self.hours//abs(self.hours)
|
|
||||||
div, mod = divmod(self.hours*s, 24)
|
|
||||||
self.hours = mod*s
|
|
||||||
self.days += div*s
|
|
||||||
if abs(self.months) > 11:
|
|
||||||
s = self.months//abs(self.months)
|
|
||||||
div, mod = divmod(self.months*s, 12)
|
|
||||||
self.months = mod*s
|
|
||||||
self.years += div*s
|
|
||||||
if (self.hours or self.minutes or self.seconds or self.microseconds or
|
|
||||||
self.hour is not None or self.minute is not None or
|
|
||||||
self.second is not None or self.microsecond is not None):
|
|
||||||
self._has_time = 1
|
|
||||||
else:
|
|
||||||
self._has_time = 0
|
|
||||||
|
|
||||||
def _set_months(self, months):
|
|
||||||
self.months = months
|
|
||||||
if abs(self.months) > 11:
|
|
||||||
s = self.months//abs(self.months)
|
|
||||||
div, mod = divmod(self.months*s, 12)
|
|
||||||
self.months = mod*s
|
|
||||||
self.years = div*s
|
|
||||||
else:
|
|
||||||
self.years = 0
|
|
||||||
|
|
||||||
def __radd__(self, other):
|
|
||||||
if not isinstance(other, datetime.date):
|
|
||||||
raise TypeError("unsupported type for add operation")
|
|
||||||
elif self._has_time and not isinstance(other, datetime.datetime):
|
|
||||||
other = datetime.datetime.fromordinal(other.toordinal())
|
|
||||||
year = (self.year or other.year)+self.years
|
|
||||||
month = self.month or other.month
|
|
||||||
if self.months:
|
|
||||||
assert 1 <= abs(self.months) <= 12
|
|
||||||
month += self.months
|
|
||||||
if month > 12:
|
|
||||||
year += 1
|
|
||||||
month -= 12
|
|
||||||
elif month < 1:
|
|
||||||
year -= 1
|
|
||||||
month += 12
|
|
||||||
day = min(calendar.monthrange(year, month)[1],
|
|
||||||
self.day or other.day)
|
|
||||||
repl = {"year": year, "month": month, "day": day}
|
|
||||||
for attr in ["hour", "minute", "second", "microsecond"]:
|
|
||||||
value = getattr(self, attr)
|
|
||||||
if value is not None:
|
|
||||||
repl[attr] = value
|
|
||||||
days = self.days
|
|
||||||
if self.leapdays and month > 2 and calendar.isleap(year):
|
|
||||||
days += self.leapdays
|
|
||||||
ret = (other.replace(**repl)
|
|
||||||
+ datetime.timedelta(days=days,
|
|
||||||
hours=self.hours,
|
|
||||||
minutes=self.minutes,
|
|
||||||
seconds=self.seconds,
|
|
||||||
microseconds=self.microseconds))
|
|
||||||
if self.weekday:
|
|
||||||
weekday, nth = self.weekday.weekday, self.weekday.n or 1
|
|
||||||
jumpdays = (abs(nth)-1)*7
|
|
||||||
if nth > 0:
|
|
||||||
jumpdays += (7-ret.weekday()+weekday)%7
|
|
||||||
else:
|
|
||||||
jumpdays += (ret.weekday()-weekday)%7
|
|
||||||
jumpdays *= -1
|
|
||||||
ret += datetime.timedelta(days=jumpdays)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def __rsub__(self, other):
|
|
||||||
return self.__neg__().__radd__(other)
|
|
||||||
|
|
||||||
def __add__(self, other):
|
|
||||||
if not isinstance(other, relativedelta):
|
|
||||||
raise TypeError("unsupported type for add operation")
|
|
||||||
return relativedelta(years=other.years+self.years,
|
|
||||||
months=other.months+self.months,
|
|
||||||
days=other.days+self.days,
|
|
||||||
hours=other.hours+self.hours,
|
|
||||||
minutes=other.minutes+self.minutes,
|
|
||||||
seconds=other.seconds+self.seconds,
|
|
||||||
microseconds=other.microseconds+self.microseconds,
|
|
||||||
leapdays=other.leapdays or self.leapdays,
|
|
||||||
year=other.year or self.year,
|
|
||||||
month=other.month or self.month,
|
|
||||||
day=other.day or self.day,
|
|
||||||
weekday=other.weekday or self.weekday,
|
|
||||||
hour=other.hour or self.hour,
|
|
||||||
minute=other.minute or self.minute,
|
|
||||||
second=other.second or self.second,
|
|
||||||
microsecond=other.second or self.microsecond)
|
|
||||||
|
|
||||||
def __sub__(self, other):
|
|
||||||
if not isinstance(other, relativedelta):
|
|
||||||
raise TypeError("unsupported type for sub operation")
|
|
||||||
return relativedelta(years=other.years-self.years,
|
|
||||||
months=other.months-self.months,
|
|
||||||
days=other.days-self.days,
|
|
||||||
hours=other.hours-self.hours,
|
|
||||||
minutes=other.minutes-self.minutes,
|
|
||||||
seconds=other.seconds-self.seconds,
|
|
||||||
microseconds=other.microseconds-self.microseconds,
|
|
||||||
leapdays=other.leapdays or self.leapdays,
|
|
||||||
year=other.year or self.year,
|
|
||||||
month=other.month or self.month,
|
|
||||||
day=other.day or self.day,
|
|
||||||
weekday=other.weekday or self.weekday,
|
|
||||||
hour=other.hour or self.hour,
|
|
||||||
minute=other.minute or self.minute,
|
|
||||||
second=other.second or self.second,
|
|
||||||
microsecond=other.second or self.microsecond)
|
|
||||||
|
|
||||||
def __neg__(self):
|
|
||||||
return relativedelta(years=-self.years,
|
|
||||||
months=-self.months,
|
|
||||||
days=-self.days,
|
|
||||||
hours=-self.hours,
|
|
||||||
minutes=-self.minutes,
|
|
||||||
seconds=-self.seconds,
|
|
||||||
microseconds=-self.microseconds,
|
|
||||||
leapdays=self.leapdays,
|
|
||||||
year=self.year,
|
|
||||||
month=self.month,
|
|
||||||
day=self.day,
|
|
||||||
weekday=self.weekday,
|
|
||||||
hour=self.hour,
|
|
||||||
minute=self.minute,
|
|
||||||
second=self.second,
|
|
||||||
microsecond=self.microsecond)
|
|
||||||
|
|
||||||
def __nonzero__(self):
|
|
||||||
return not (not self.years and
|
|
||||||
not self.months and
|
|
||||||
not self.days and
|
|
||||||
not self.hours and
|
|
||||||
not self.minutes and
|
|
||||||
not self.seconds and
|
|
||||||
not self.microseconds and
|
|
||||||
not self.leapdays and
|
|
||||||
self.year is None and
|
|
||||||
self.month is None and
|
|
||||||
self.day is None and
|
|
||||||
self.weekday is None and
|
|
||||||
self.hour is None and
|
|
||||||
self.minute is None and
|
|
||||||
self.second is None and
|
|
||||||
self.microsecond is None)
|
|
||||||
|
|
||||||
def __mul__(self, other):
|
|
||||||
f = float(other)
|
|
||||||
return relativedelta(years=self.years*f,
|
|
||||||
months=self.months*f,
|
|
||||||
days=self.days*f,
|
|
||||||
hours=self.hours*f,
|
|
||||||
minutes=self.minutes*f,
|
|
||||||
seconds=self.seconds*f,
|
|
||||||
microseconds=self.microseconds*f,
|
|
||||||
leapdays=self.leapdays,
|
|
||||||
year=self.year,
|
|
||||||
month=self.month,
|
|
||||||
day=self.day,
|
|
||||||
weekday=self.weekday,
|
|
||||||
hour=self.hour,
|
|
||||||
minute=self.minute,
|
|
||||||
second=self.second,
|
|
||||||
microsecond=self.microsecond)
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
|
||||||
if not isinstance(other, relativedelta):
|
|
||||||
return False
|
|
||||||
if self.weekday or other.weekday:
|
|
||||||
if not self.weekday or not other.weekday:
|
|
||||||
return False
|
|
||||||
if self.weekday.weekday != other.weekday.weekday:
|
|
||||||
return False
|
|
||||||
n1, n2 = self.weekday.n, other.weekday.n
|
|
||||||
if n1 != n2 and not ((not n1 or n1 == 1) and (not n2 or n2 == 1)):
|
|
||||||
return False
|
|
||||||
return (self.years == other.years and
|
|
||||||
self.months == other.months and
|
|
||||||
self.days == other.days and
|
|
||||||
self.hours == other.hours and
|
|
||||||
self.minutes == other.minutes and
|
|
||||||
self.seconds == other.seconds and
|
|
||||||
self.leapdays == other.leapdays and
|
|
||||||
self.year == other.year and
|
|
||||||
self.month == other.month and
|
|
||||||
self.day == other.day and
|
|
||||||
self.hour == other.hour and
|
|
||||||
self.minute == other.minute and
|
|
||||||
self.second == other.second and
|
|
||||||
self.microsecond == other.microsecond)
|
|
||||||
|
|
||||||
def __ne__(self, other):
|
|
||||||
return not self.__eq__(other)
|
|
||||||
|
|
||||||
def __div__(self, other):
|
|
||||||
return self.__mul__(1/float(other))
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
l = []
|
|
||||||
for attr in ["years", "months", "days", "leapdays",
|
|
||||||
"hours", "minutes", "seconds", "microseconds"]:
|
|
||||||
value = getattr(self, attr)
|
|
||||||
if value:
|
|
||||||
l.append("%s=%+d" % (attr, value))
|
|
||||||
for attr in ["year", "month", "day", "weekday",
|
|
||||||
"hour", "minute", "second", "microsecond"]:
|
|
||||||
value = getattr(self, attr)
|
|
||||||
if value is not None:
|
|
||||||
l.append("%s=%s" % (attr, value))
|
|
||||||
return "%s(%s)" % (self.__class__.__name__, ", ".join(l))
|
|
Loading…
Reference in New Issue
Block a user