Initial Commit
This commit is contained in:
36
environment.py
Normal file
36
environment.py
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
APPEND_SYS_PATH='/home/pi/.kodi/addons/plugin.video.fox.news/resources/lib'
|
||||||
|
PATH_VIDEO_DATABASE='/home/pi/.kodi/addons/plugin.video.fox.news/resources/lib/archive'
|
||||||
|
USE_ICON_URL=True
|
||||||
|
PATH_LOG_FILE="/home/pi/.kodi/temp/MyLog.log"
|
||||||
|
FOX_NEWS_URL="https://www.foxnews.com/video"
|
||||||
|
FOX_NEWS_US_URL="hhttps://www.foxnews.com/video/topics/us"
|
||||||
|
FOX_NEWS_EXCLUSIVE_URL="https://foxnews.com"
|
||||||
|
FOX_NEWS_AMERICAS_NEWSROOM_URL="https://www.foxnews.com/video/shows/americas-newsroom"
|
||||||
|
FOX_NEWS_OUTNUMBERED_URL="https://www.foxnews.com/video/shows/outnumbered"
|
||||||
|
SELECTED_ARCHIVE_URL="https://www.foxnews.com/video/dummy"
|
||||||
|
#FOX_NEWS_ICON_OF_LAST_RESORT="https://static.foxnews.com/static/orion/styles/img/fox-news/favicons/apple-touch-icon-180x180.png"
|
||||||
|
#ENABLE_USE_ICON_OF_LAST_RESORT=False
|
||||||
|
|
||||||
|
|
||||||
|
VIDEODB_AMERICAS_NEWSROOM_FILENAME="videodb_americasnewsroom.txt"
|
||||||
|
VIDEODB_OUTNUMBERED_FILENAME="videodb_outnumbered.txt"
|
||||||
|
VIDEODB_FILENAME="videodb.txt"
|
||||||
|
VIDEODB_EXCLUSIVE_FILENAME="videodb_exc.txt"
|
||||||
|
VIDEODB_US_FILENAME="videodb_us.txt"
|
||||||
|
ARCHIVEDB_FILENAME="archivedb.txt"
|
||||||
|
|
||||||
|
CACHE_EXPIRY_MINS=10
|
||||||
|
|
||||||
|
class PathHelper:
|
||||||
|
pathChar="/"
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def makePathFileName(file,path):
|
||||||
|
while file.endswith(PathHelper.pathChar):
|
||||||
|
file=file[:-1]
|
||||||
|
while path.endswith(PathHelper.pathChar):
|
||||||
|
path=path[:-1]
|
||||||
|
return path+PathHelper.pathChar+file
|
||||||
358
newsfeed.py
Normal file
358
newsfeed.py
Normal file
@@ -0,0 +1,358 @@
|
|||||||
|
import tkinter as tk
|
||||||
|
import math
|
||||||
|
from functools import partial
|
||||||
|
import json
|
||||||
|
import webbrowser
|
||||||
|
import os
|
||||||
|
import requests
|
||||||
|
import traceback
|
||||||
|
import time
|
||||||
|
import glob
|
||||||
|
import re
|
||||||
|
import shutil
|
||||||
|
from datetime import timedelta
|
||||||
|
from datetime import datetime
|
||||||
|
from datetime import timezone
|
||||||
|
from environment import *
|
||||||
|
from utility import *
|
||||||
|
|
||||||
|
class Video:
|
||||||
|
def __init__(self):
|
||||||
|
self.description=None
|
||||||
|
self.url=None
|
||||||
|
self.icon=None
|
||||||
|
self.timestamp=DateTime()
|
||||||
|
self.feedTimeOffset='just now'
|
||||||
|
|
||||||
|
def __init__(self, description, url):
|
||||||
|
self.description=description
|
||||||
|
self.url=url
|
||||||
|
self.icon=None
|
||||||
|
self.timestamp=DateTime()
|
||||||
|
self.feedTimeOffset='just now'
|
||||||
|
|
||||||
|
def __init__(self, description, url, icon, timestamp=None):
|
||||||
|
self.description=description
|
||||||
|
self.url=url
|
||||||
|
self.icon=icon
|
||||||
|
if None==timestamp:
|
||||||
|
self.timestamp=DateTime()
|
||||||
|
else:
|
||||||
|
self.timestamp=timestamp
|
||||||
|
self.feedTimeOffset='just now'
|
||||||
|
|
||||||
|
def getDescription(self):
|
||||||
|
return self.description
|
||||||
|
|
||||||
|
def getUrl(self):
|
||||||
|
return self.url
|
||||||
|
|
||||||
|
def getIcon(self):
|
||||||
|
return self.icon
|
||||||
|
|
||||||
|
def getTimestamp(self):
|
||||||
|
return self.timestamp
|
||||||
|
|
||||||
|
def setFeedTime(self,feedtime):
|
||||||
|
self.feedtime=feedtime
|
||||||
|
|
||||||
|
def getFeedTime(self):
|
||||||
|
return self.feedtime
|
||||||
|
|
||||||
|
def getFeedTimeOffset(self):
|
||||||
|
return self.feedTimeOffset
|
||||||
|
|
||||||
|
def setFeedTimeOffset(self, feedtimeoffset):
|
||||||
|
self.feedTimeOffset=feedtimeoffset
|
||||||
|
|
||||||
|
def toString(self):
|
||||||
|
return(self.description+"|"+self.url+"|"+self.icon+"|"+self.timestamp.toString())
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def fromString(line):
|
||||||
|
splits=line.split("|")
|
||||||
|
description=splits[0].strip()
|
||||||
|
url=splits[1].strip()
|
||||||
|
icon=splits[2].strip()
|
||||||
|
timestamp=DateTime(splits[3].strip())
|
||||||
|
return(Video(description,url,icon,timestamp))
|
||||||
|
|
||||||
|
class NewsFeed:
|
||||||
|
def __init__(self, logger=None):
|
||||||
|
self.logger=logger
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def isResourceAvailable(url):
|
||||||
|
try:
|
||||||
|
response=requests.head(url, timeout=2.5)
|
||||||
|
if not response.ok:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def getItemsInFeed(self,url):
|
||||||
|
now=datetime.now()
|
||||||
|
sections=Sections()
|
||||||
|
videos = {}
|
||||||
|
httpNetRequest=HttpNetRequest()
|
||||||
|
response=httpNetRequest=httpNetRequest.getHttpNetRequest(url)
|
||||||
|
status=response.status_code
|
||||||
|
searchIndex=0
|
||||||
|
response.close()
|
||||||
|
if status!=200:
|
||||||
|
return None
|
||||||
|
while -1!= searchIndex:
|
||||||
|
video, searchIndex= sections.getItemsInSection(response.text,"article",searchIndex)
|
||||||
|
if video is not None and not (video.description in videos):
|
||||||
|
videos[video.description]=video
|
||||||
|
video.setFeedTime(DateTimeHelper.applyRelativeTime(now,video.feedTimeOffset))
|
||||||
|
videoList=NewsFeed.filterFeedMaxDays(list(videos.values()),7)
|
||||||
|
# videoList=list(videos.values())
|
||||||
|
videoList=sorted(videoList, key=lambda x:x.getFeedTime(),reverse=True)
|
||||||
|
return (videoList)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def filterFeedMaxDays(videos,days):
|
||||||
|
now=datetime.now()
|
||||||
|
filteredList=[]
|
||||||
|
for video in videos:
|
||||||
|
delta=now-video.getFeedTime()
|
||||||
|
if delta.days <= days:
|
||||||
|
filteredList.insert(0,video)
|
||||||
|
return filteredList
|
||||||
|
|
||||||
|
class Sections:
|
||||||
|
def __init__(self):
|
||||||
|
self.dummy=None
|
||||||
|
|
||||||
|
def getItemsInSection(self, strInput, sectionName, searchIndex):
|
||||||
|
video=None
|
||||||
|
startSection='<'+sectionName
|
||||||
|
endSection='</'+sectionName
|
||||||
|
|
||||||
|
startIndex=strInput.find(startSection,searchIndex)
|
||||||
|
if -1 == startIndex:
|
||||||
|
searchIndex=-1
|
||||||
|
return video, searchIndex
|
||||||
|
|
||||||
|
endIndex=strInput.find(endSection,startIndex)
|
||||||
|
if -1 == endIndex:
|
||||||
|
searchIndex=-1
|
||||||
|
return video, searchIndex
|
||||||
|
|
||||||
|
searchIndex=endIndex+len(endSection)
|
||||||
|
strContainingString=strInput[startIndex:endIndex+1+len(endSection)]
|
||||||
|
|
||||||
|
if not strContainingString or strContainingString=="":
|
||||||
|
return video, searchIndex
|
||||||
|
|
||||||
|
indexPreview=strContainingString.find("preview=\"")
|
||||||
|
if -1 == indexPreview:
|
||||||
|
return video, searchIndex
|
||||||
|
previewUrl=strContainingString[indexPreview:]
|
||||||
|
previewUrl=self.betweenString(previewUrl,'"','"')
|
||||||
|
if "tokenvod" in previewUrl:
|
||||||
|
return video, searchIndex
|
||||||
|
|
||||||
|
indexDescription=strContainingString.index("alt=\"")
|
||||||
|
description=strContainingString[indexDescription:]
|
||||||
|
description=self.betweenString(description,'"','"')
|
||||||
|
description=self.removeHtml(description)
|
||||||
|
description=description.replace("- Fox News","")
|
||||||
|
if "vod.foxbusiness" in description:
|
||||||
|
return video, searchIndex
|
||||||
|
indexDuration=strContainingString.index("<div class=\"duration\">")
|
||||||
|
if -1 != indexDuration:
|
||||||
|
strDuration=strContainingString[indexDuration:]
|
||||||
|
strDuration=self.betweenString(strDuration,">","<")
|
||||||
|
description=description+" - "+strDuration
|
||||||
|
indexPublication=strContainingString.index("<div class=\"pub-date\">")
|
||||||
|
if -1 != indexPublication:
|
||||||
|
strPublication=strContainingString[indexPublication:]
|
||||||
|
strPublication=self.betweenString(strPublication,"<time>","</time>")
|
||||||
|
description=description+" ("+strPublication+")"
|
||||||
|
icon=None
|
||||||
|
indexIcon=strContainingString.index("srcset=")
|
||||||
|
if -1 != indexIcon:
|
||||||
|
icon=strContainingString[indexIcon:]
|
||||||
|
icon=self.betweenString(icon,"\"","\"")
|
||||||
|
splits=icon.split(',')
|
||||||
|
icon=self.betweenString(splits[len(splits)-1],None,'?')
|
||||||
|
icon=icon.strip()
|
||||||
|
video=Video(description,previewUrl,icon)
|
||||||
|
video.feedTimeOffset=strPublication
|
||||||
|
return video, searchIndex
|
||||||
|
|
||||||
|
def getVideoIdInSection(self, strInput, sectionName, searchIndex):
|
||||||
|
video=None
|
||||||
|
startSection='<'+sectionName
|
||||||
|
endSection='</'+sectionName
|
||||||
|
|
||||||
|
startIndex=strInput.find(startSection,searchIndex)
|
||||||
|
if -1 == startIndex:
|
||||||
|
searchIndex=-1
|
||||||
|
return video, searchIndex
|
||||||
|
|
||||||
|
endIndex=strInput.find(endSection,startIndex)
|
||||||
|
if -1 == endIndex:
|
||||||
|
searchIndex=-1
|
||||||
|
return video, searchIndex
|
||||||
|
|
||||||
|
searchIndex=endIndex+len(endSection)
|
||||||
|
strContainingString=strInput[startIndex:endIndex+1+len(endSection)]
|
||||||
|
if not strContainingString or strContainingString=="":
|
||||||
|
return video, searchIndex
|
||||||
|
indexVideoId=strContainingString.find("data-video-id")
|
||||||
|
if -1 ==indexVideoId:
|
||||||
|
return video, searchIndex
|
||||||
|
videoId=strContainingString[indexVideoId:]
|
||||||
|
videoId=self.betweenString(videoId,"\"","\"")
|
||||||
|
return videoId, searchIndex
|
||||||
|
|
||||||
|
def getVideoContentInSection(self, strInput):
|
||||||
|
video=None
|
||||||
|
searchItem="\"contentUrl\":"
|
||||||
|
indexContentUrl=strInput.find(searchItem)
|
||||||
|
if -1 == indexContentUrl:
|
||||||
|
return None
|
||||||
|
strContentUrl=strInput[indexContentUrl+len(searchItem):]
|
||||||
|
strContentUrl=self.betweenString(strContentUrl,"\"","\"")
|
||||||
|
strContentUrl=strContentUrl.strip()
|
||||||
|
|
||||||
|
searchItem="\"description\":"
|
||||||
|
indexDescription=strInput.find(searchItem)
|
||||||
|
if -1 == indexDescription:
|
||||||
|
return None
|
||||||
|
strDescription=strInput[indexDescription+len(searchItem):]
|
||||||
|
strDescription=self.betweenString(strDescription,"\"","\"")
|
||||||
|
strDescription=strDescription.strip()
|
||||||
|
|
||||||
|
searchItem="\"thumbnailUrl\":"
|
||||||
|
indexIcon=strInput.find(searchItem)
|
||||||
|
if -1 == indexIcon:
|
||||||
|
return None
|
||||||
|
strIcon=strInput[indexIcon+len(searchItem):]
|
||||||
|
strIcon=self.betweenString(strIcon,"\"","\"")
|
||||||
|
strIcon=strIcon.strip()
|
||||||
|
|
||||||
|
searchItem="\"duration\""
|
||||||
|
indexDuration=strInput.find(searchItem)
|
||||||
|
if -1 != indexDuration:
|
||||||
|
strDuration=strInput[indexDuration+len(searchItem):]
|
||||||
|
strDuration=self.betweenString(strDuration,"\"","\"")
|
||||||
|
strDuration=strDuration.strip()
|
||||||
|
minutes, seconds = parseDuration(strDuration)
|
||||||
|
if None!=minutes and None!=seconds:
|
||||||
|
strDescription=strDescription+" - "+minutes+":"+seconds
|
||||||
|
video=Video(strDescription,strContentUrl,strIcon)
|
||||||
|
return video
|
||||||
|
|
||||||
|
def betweenString(self, strItem, strBegin, strEnd ):
|
||||||
|
return StringHelper.betweenString(strItem, strBegin, strEnd)
|
||||||
|
|
||||||
|
def removeHtml(self,strItem):
|
||||||
|
if strItem is None:
|
||||||
|
return None
|
||||||
|
codes={"'","»"}
|
||||||
|
for code in codes:
|
||||||
|
strItem=strItem.replace(code,"'")
|
||||||
|
strItem=strItem.replace("&","&")
|
||||||
|
strItem=strItem.replace("‘","'")
|
||||||
|
strItem=strItem.replace("’","'")
|
||||||
|
strItem=strItem.replace("—","-")
|
||||||
|
strItem=strItem.replace("???","'")
|
||||||
|
return strItem
|
||||||
|
|
||||||
|
def pad(str,filler,length):
|
||||||
|
stringLength=len(str)
|
||||||
|
sb=""
|
||||||
|
if stringLength>=length:
|
||||||
|
return str
|
||||||
|
while stringLength < length:
|
||||||
|
sb=sb+filler
|
||||||
|
stringLength=stringLength+1
|
||||||
|
return sb+str
|
||||||
|
|
||||||
|
def parseDuration(strDuration):
|
||||||
|
expression=re.compile(r"\d+")
|
||||||
|
result=expression.findall(strDuration)
|
||||||
|
if 2!=len(result):
|
||||||
|
return None, None
|
||||||
|
return pad(result[0],'0',2), pad(result[1],'0',2)
|
||||||
|
|
||||||
|
|
||||||
|
def selectedItem(event):
|
||||||
|
widget=event.widget
|
||||||
|
selectedIndex=int(widget.curselection()[0])
|
||||||
|
itemsInList=len(videoCollection.getVideoList())
|
||||||
|
if selectedIndex >=0 and selectedIndex < itemsInList:
|
||||||
|
videoUrl=videoCollection.getVideoList()[selectedIndex].getUrl()
|
||||||
|
webbrowser.open(videoUrl)
|
||||||
|
|
||||||
|
def refresh():
|
||||||
|
listbox.delete(0,'end')
|
||||||
|
loadVideos()
|
||||||
|
|
||||||
|
def loadVideos():
|
||||||
|
newsfeed=NewsFeed()
|
||||||
|
videos=newsfeed.getItemsInFeed(FOX_NEWS_URL)
|
||||||
|
itemIndex=1
|
||||||
|
for video in videos:
|
||||||
|
listbox.insert(itemIndex,video.getDescription())
|
||||||
|
itemIndex=itemIndex+1
|
||||||
|
videoCollection.setVideoList(videos)
|
||||||
|
|
||||||
|
class VideoCollection:
|
||||||
|
def __init__(self):
|
||||||
|
self.videoList=[]
|
||||||
|
|
||||||
|
def getVideoList(self):
|
||||||
|
return self.videoList
|
||||||
|
|
||||||
|
def setVideoList(self,videoList):
|
||||||
|
self.videoList=videoList
|
||||||
|
|
||||||
|
videoCollection=VideoCollection()
|
||||||
|
|
||||||
|
master = tk.Tk()
|
||||||
|
master.geometry("450x300")
|
||||||
|
#master.geometry("640x480")
|
||||||
|
|
||||||
|
#Frame
|
||||||
|
frame=tk.Frame(master,height=100)
|
||||||
|
frame.pack(fill='both',expand='true')
|
||||||
|
|
||||||
|
bottomframe=tk.Frame()
|
||||||
|
bottomframe.pack(side='bottom')
|
||||||
|
|
||||||
|
#Entry
|
||||||
|
label_heading = tk.Label(frame, text = "Fox News Video Feed",font='arial 13 bold',background='blue',foreground='white')
|
||||||
|
label_heading.pack(side='top', fill='both')
|
||||||
|
|
||||||
|
#yscrollbar for list
|
||||||
|
yscrollbar=tk.Scrollbar(frame)
|
||||||
|
yscrollbar.pack(side=tk.RIGHT, fill=tk.Y)
|
||||||
|
|
||||||
|
#xscrollbar for list
|
||||||
|
xscrollbar=tk.Scrollbar(frame, orient=tk.HORIZONTAL)
|
||||||
|
xscrollbar.pack(side=tk.BOTTOM,fill=tk.X)
|
||||||
|
|
||||||
|
# List
|
||||||
|
listbox=tk.Listbox(frame,selectmode='single',yscrollcommand=yscrollbar.set,xscrollcommand=xscrollbar.set)
|
||||||
|
listbox.pack(side='left', fill='both')
|
||||||
|
listbox.bind('<Double-Button>',selectedItem)
|
||||||
|
listbox.configure(background='skyblue4',foreground='white',font='arial 8 bold',width=0)
|
||||||
|
|
||||||
|
#configure the scrollbar
|
||||||
|
yscrollbar.config(command=listbox.yview)
|
||||||
|
xscrollbar.config(command=listbox.xview)
|
||||||
|
|
||||||
|
#Button
|
||||||
|
btn_refresh = tk.Button(bottomframe,text = 'Refresh',command = refresh)
|
||||||
|
btn_refresh.pack(side='bottom')
|
||||||
|
|
||||||
|
loadVideos()
|
||||||
|
listbox.focus_set()
|
||||||
|
|
||||||
|
master.mainloop()
|
||||||
231
utility.py
Normal file
231
utility.py
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
import time
|
||||||
|
import webbrowser
|
||||||
|
import requests
|
||||||
|
from datetime import timedelta
|
||||||
|
from datetime import datetime
|
||||||
|
from datetime import timezone
|
||||||
|
from environment import *
|
||||||
|
|
||||||
|
class myLog():
|
||||||
|
def __init__(self):
|
||||||
|
self._file = open(PATH_LOG_FILE,"a",encoding='utf-8')
|
||||||
|
|
||||||
|
def write(self,item):
|
||||||
|
currentDateTime = DateTimeHelper.getCurrentDateTime()
|
||||||
|
strCurrentDateTime = DateTimeHelper.getDateTimeAsString(currentDateTime)
|
||||||
|
strOutput = '[' + strCurrentDateTime +'] '+item
|
||||||
|
self._file.write(strOutput)
|
||||||
|
self._file.write("\n")
|
||||||
|
self._file.flush()
|
||||||
|
|
||||||
|
class StringHelper:
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def betweenString(strItem, strBegin, strEnd):
|
||||||
|
if strItem is None:
|
||||||
|
return None
|
||||||
|
index=-1
|
||||||
|
if strBegin is None:
|
||||||
|
index=0
|
||||||
|
else:
|
||||||
|
index = strItem.index(strBegin)
|
||||||
|
if -1==index:
|
||||||
|
return None
|
||||||
|
str=None
|
||||||
|
if strBegin is not None:
|
||||||
|
str=strItem[index+len(strBegin):]
|
||||||
|
else:
|
||||||
|
str=strItem
|
||||||
|
if strEnd is None:
|
||||||
|
return str
|
||||||
|
index=str.index(strEnd)
|
||||||
|
if -1==index :
|
||||||
|
return None
|
||||||
|
sb=""
|
||||||
|
for strIndex in range(0, len(str)-1):
|
||||||
|
if index==strIndex:
|
||||||
|
break
|
||||||
|
sb=sb+str[strIndex]
|
||||||
|
return (sb)
|
||||||
|
|
||||||
|
class HttpNetRequest:
|
||||||
|
def __init__(self):
|
||||||
|
self.Message=""
|
||||||
|
|
||||||
|
def getHttpNetRequest(self,url):
|
||||||
|
retrycount=0
|
||||||
|
maxretries=5
|
||||||
|
while retrycount<maxretries:
|
||||||
|
try:
|
||||||
|
response=requests.get(url, timeout=10)
|
||||||
|
return response
|
||||||
|
except:
|
||||||
|
retrycount=retrycount+1
|
||||||
|
if retrycount > maxretries:
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
class DateTimeHelper:
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __init__(self,capturedatetime,timeChange):
|
||||||
|
self.datetimestamp=capturedatetime
|
||||||
|
self.timeChange=timeChange
|
||||||
|
self.offsetTime=DateTimeHelper.applyRelativeTime(self.datetimestamp, self.timeChange)
|
||||||
|
|
||||||
|
def getDateTimeStamp(self):
|
||||||
|
return self.datetimestamp
|
||||||
|
|
||||||
|
def getTimeChange(self):
|
||||||
|
return self.timeChange
|
||||||
|
|
||||||
|
def getOffsetTime(self):
|
||||||
|
return self.offsetTime
|
||||||
|
|
||||||
|
def getOffsetTimeAsString(self):
|
||||||
|
return DateTimeHelper.getDateTimeAsString(self.offsetTime)
|
||||||
|
|
||||||
|
def toString(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getDateTimeAsString(someDateTime):
|
||||||
|
if(not isinstance(someDateTime,datetime)):
|
||||||
|
raise Exception('Invalid type for parameter')
|
||||||
|
return someDateTime.strftime("%m-%d-%Y %H:%M:%S")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getDateTimeFromString(someDateTimeString):
|
||||||
|
if(not isinstance(someDateTimeString,str)):
|
||||||
|
raise Exception('Invalid type for parameter')
|
||||||
|
return DateTimeHelper.strptime(someDateTimeString,"%m-%d-%Y %H:%M:%S")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getCurrentDateTime():
|
||||||
|
return datetime.now()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def strptime(theTime,theFormat):
|
||||||
|
try:
|
||||||
|
return datetime.strptime(theTime,theFormat)
|
||||||
|
except:
|
||||||
|
return datetime(*(time.strptime(theTime,theFormat)[0:6]))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def canstrptime(theTime,theFormat):
|
||||||
|
try:
|
||||||
|
datetime.strptime(theTime,theFormat)
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# returns a datetime
|
||||||
|
@staticmethod
|
||||||
|
def applyRelativeTime(sometime,relativetime):
|
||||||
|
if(not isinstance(sometime,datetime)):
|
||||||
|
raise Exception('Invalid type for parameter')
|
||||||
|
if(not isinstance(relativetime,str)):
|
||||||
|
raise Exception('Invalid type for parameter')
|
||||||
|
if DateTimeHelper.canstrptime(relativetime,'%B %d, %Y'):
|
||||||
|
sometime = DateTimeHelper.strptime(relativetime,'%B %d, %Y')
|
||||||
|
return sometime
|
||||||
|
if relativetime=='just now':
|
||||||
|
return sometime
|
||||||
|
if relativetime=='just in':
|
||||||
|
return sometime
|
||||||
|
relativetimesplit=relativetime.split()
|
||||||
|
if len(relativetimesplit)==2:
|
||||||
|
year=datetime.now().year
|
||||||
|
relativetimex=relativetime+', '+str(year)
|
||||||
|
relativeDate = DateTimeHelper.strptime(relativetimex, '%B %d, %Y')
|
||||||
|
if(relativeDate>datetime.now()):
|
||||||
|
year=datetime.now().year-1
|
||||||
|
relativetimex=relativetime+', '+str(year)
|
||||||
|
relativeDate=DateTimeHelper.strptime(relativetimex,'%B %d, %Y')
|
||||||
|
days=sometime-relativeDate
|
||||||
|
sometime=sometime-days
|
||||||
|
elif relativetimesplit[1]=='hour' or relativetimesplit[1]=='hours':
|
||||||
|
hours=int(relativetimesplit[0])
|
||||||
|
sometime=sometime-timedelta(hours=hours)
|
||||||
|
elif relativetimesplit[1]=='day' or relativetimesplit[1]=='days':
|
||||||
|
days=int(relativetimesplit[0])
|
||||||
|
sometime=sometime-timedelta(days=days)
|
||||||
|
elif relativetimesplit[1]=='minute' or relativetimesplit[1]=='minutes':
|
||||||
|
minutes=int(relativetimesplit[0])
|
||||||
|
sometime=sometime-timedelta(minutes=minutes)
|
||||||
|
elif len(relativetimesplit)==3: # '16 mins ago' '2 hours ago'
|
||||||
|
if relativetimesplit[1]=='mins':
|
||||||
|
minutes=int(relativetimesplit[0])
|
||||||
|
sometime=sometime-timedelta(minutes=minutes)
|
||||||
|
elif relativetimesplit[1]=='hours':
|
||||||
|
hours=int(relativetimesplit[0])
|
||||||
|
sometime=sometime-timedelta(hours=hours)
|
||||||
|
elif relativetimesplit[1]=='day' or relativetimesplit[1]=='days':
|
||||||
|
days=int(relativetimesplit[0])
|
||||||
|
sometime=sometime-timedelta(days=days)
|
||||||
|
return sometime
|
||||||
|
|
||||||
|
class DateTime:
|
||||||
|
def __init__(self):
|
||||||
|
self.date=DateTime.getCurrentTime()
|
||||||
|
|
||||||
|
def __init__(self,strDate=None):
|
||||||
|
if None!=strDate:
|
||||||
|
self.date=DateTime.dateFromString(strDate)
|
||||||
|
else:
|
||||||
|
self.date=DateTime.getCurrentTime()
|
||||||
|
|
||||||
|
def toString(self):
|
||||||
|
return DateTime.dateToString(self.date)
|
||||||
|
|
||||||
|
def deltaTime(self,someDate):
|
||||||
|
return DateTime.deltaTime(self.date,someDate)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def dateToString(someDate):
|
||||||
|
return str(someDate)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def dateFromString(strDate):
|
||||||
|
return datetime.fromisoformat(strDate)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def now():
|
||||||
|
return DateTime.getCurrentTime()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getCurrentTime():
|
||||||
|
return datetime.now(timezone.utc)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def sortList(dateList):
|
||||||
|
dateList.sort(key=lambda x:x.toString())
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def deltaTime(startTime,endTime):
|
||||||
|
if startTime > endTime:
|
||||||
|
timedelta=startTime-endTime
|
||||||
|
else:
|
||||||
|
timedelta=endTime-startTime
|
||||||
|
days, seconds=timedelta.days, timedelta.seconds
|
||||||
|
hours=timedelta.total_seconds()//3600
|
||||||
|
minutes=(seconds %3600)//60
|
||||||
|
seconds=seconds%60
|
||||||
|
return days, hours, minutes, seconds
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#currentDate=DateTimeHelper.getCurrentDateTime()
|
||||||
|
#strDateTime=DateTimeHelper.getDateTimeAsString(currentDate)
|
||||||
|
#print(strDateTime)
|
||||||
|
#relativeTime=DateTimeHelper.applyRelativeTime(currentDate,'October 9')
|
||||||
|
#strDateTime=DateTimeHelper.getDateTimeAsString(relativeTime)
|
||||||
|
#print(relativeTime)
|
||||||
|
#if(relativeTime>currentDate):
|
||||||
|
# print('It is greater')
|
||||||
|
|
||||||
Reference in New Issue
Block a user