Massive refactoring, json functionality added
This commit is contained in:
parent
038fbd0f9f
commit
75a2dff92d
|
@ -14,7 +14,7 @@ This project is currently very WIP, the todo list is:
|
|||
- [ ] Task lists as calendar tags (maybe?)
|
||||
- [ ] Creating, modifying, removing, completing tasks
|
||||
- [ ] Offline caching
|
||||
- [ ] JSON export
|
||||
- [x] JSON export
|
||||
|
||||
# Dependencies
|
||||
```
|
||||
|
|
106
decal
106
decal
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/python
|
||||
# if you're reading the source code for this (oof), feel free to suggest improvements for this, or, well, anything above or below this comment (as long as it's not just "rewrite this entire thing in C++ for me because i think python bad", "idk how but optimize stuff kthx". just don't be a dick, ok? thanks).
|
||||
import configparser
|
||||
import datetime
|
||||
from datetime import date, timedelta
|
||||
import calendar
|
||||
import caldav
|
||||
import argparse
|
||||
|
@ -11,7 +13,7 @@ Version = "%(prog)s 0.1"
|
|||
configpath = os.getenv("HOME")+"/.config/decal.conf"
|
||||
config.read(configpath)
|
||||
#define arguments
|
||||
today = datetime.date.today()
|
||||
today = date.today()
|
||||
parser = argparse.ArgumentParser(description="Cal with events.")
|
||||
parser.add_argument("year",
|
||||
action="store",
|
||||
|
@ -64,9 +66,7 @@ args = vars(parser.parse_args())
|
|||
if args["create"]:
|
||||
print("Not implemented")
|
||||
exit(0)
|
||||
if args["json"]:
|
||||
print("Not implemented")
|
||||
exit(0)
|
||||
|
||||
#check some stuff, do some warnings, initiate the config, etc.
|
||||
if not os.path.exists(configpath):
|
||||
config['DEFAULT'] = {'uri': 'your caldav server here',
|
||||
|
@ -97,9 +97,9 @@ def gencal(year,month,firstweekday=6,cell_modifier=lambda d: d,append_year=True)
|
|||
lines = [""]*6
|
||||
monthstart = False
|
||||
counter = 0
|
||||
for date in cal.itermonthdates(year,month):
|
||||
for curdate in cal.itermonthdates(year,month):
|
||||
lines[counter//7]
|
||||
day = str(date)[-2:]
|
||||
day = str(curdate)[-2:]
|
||||
if day == "01":
|
||||
monthstart = not monthstart
|
||||
if monthstart:
|
||||
|
@ -112,7 +112,7 @@ def gencal(year,month,firstweekday=6,cell_modifier=lambda d: d,append_year=True)
|
|||
for times in range(firstweekday):
|
||||
weeklines.append(weeklines.pop(0))
|
||||
lines.insert(0," ".join(weeklines)+" ")
|
||||
lines.insert(0,datetime.date(year,month,1).strftime("%B %Y").center(21))
|
||||
lines.insert(0,date(year,month,1).strftime("%B %Y").center(21))
|
||||
lines[-1] += " "*(21-len(lines[-1]))
|
||||
return lines
|
||||
|
||||
|
@ -152,12 +152,12 @@ def span(year,month,offset):
|
|||
|
||||
#get 2 date values - start value to scan from and end value to scan up to.
|
||||
def getbounds(y,m,offset):
|
||||
start = datetime.date(y,m,1)
|
||||
start = date(y,m,1)
|
||||
postnextmonth = span(y,m,offset)
|
||||
nextmonth = span(postnextmonth[0],postnextmonth[1],-1)
|
||||
end = datetime.date(nextmonth[0],
|
||||
nextmonth[1],
|
||||
(datetime.date(postnextmonth[0],postnextmonth[1],1)-datetime.timedelta(days=1)).day)
|
||||
end = date(nextmonth[0],
|
||||
nextmonth[1],
|
||||
(date(postnextmonth[0],postnextmonth[1],1)-timedelta(days=1)).day)
|
||||
return start,end
|
||||
|
||||
# generator for year/month pairs
|
||||
|
@ -194,49 +194,73 @@ principal = client.principal()
|
|||
calendars = principal.calendars()
|
||||
|
||||
# aggregate selected calendars
|
||||
if "calendars" in config['DEFAULT']:
|
||||
def aggregateCalendars(calendars):
|
||||
calendars2 = []
|
||||
cals = config['DEFAULT']["calendars"].split(",")
|
||||
for cal in calendars:
|
||||
if cal.name in cal:
|
||||
calendars2.append(cal)
|
||||
calendars = calendars2
|
||||
return calendars2
|
||||
|
||||
# hooo boy, fun things start here.
|
||||
# we generate a dict of (year,month) pairs for easier indexing
|
||||
events = {}
|
||||
for ympair in ympairs((args['year'],args['month']),offset,dstart=args['3']):
|
||||
events[ympair] = {}
|
||||
# next, we iterate over events in each calendar, sorting them the folliwng way:
|
||||
# events[(int year,int month)][int day] = [event event1, event event2, ...]
|
||||
# looks awful, is awful, overall i love this.
|
||||
for cal in calendars:
|
||||
events_fetched = cal.date_search(start,end)
|
||||
for event in events_fetched:
|
||||
event = event.vobject_instance.vevent.contents
|
||||
curdate = event["dtstart"][0].value
|
||||
enddate = event["dtend"][0].value
|
||||
while curdate <= enddate:
|
||||
curdindex = (curdate.year,curdate.month)
|
||||
if curdindex in events:
|
||||
if not curdate.day in events[curdindex]:
|
||||
events[curdindex][curdate.day] = []
|
||||
events[curdindex][curdate.day].append(event)
|
||||
curdate += datetime.timedelta(days=1)
|
||||
# if you're reading the source code for this (oof), feel free to suggest improvements for this, or, well, anything above or below this comment (as long as it's not just "rewrite this entire thing in C++ for me because i think python bad", "idk how but optimize stuff kthx". just don't be a dick, ok? thanks).
|
||||
if "calendars" in config['DEFAULT']:
|
||||
calendars = aggregateCalendars(calendars)
|
||||
|
||||
|
||||
def daysOfEvent(event):
|
||||
event = event.vobject_instance.vevent.contents
|
||||
curdate = event["dtstart"][0].value
|
||||
enddate = event["dtend"][0].value
|
||||
while curdate <= enddate:
|
||||
if type(curdate) == datetime.datetime:
|
||||
yield str(curdate.date())
|
||||
else:
|
||||
yield str(curdate)
|
||||
curdate += timedelta(days=1)
|
||||
return
|
||||
|
||||
def jsonifyEvent(event):
|
||||
event = event.vobject_instance.vevent.contents
|
||||
evdata = {
|
||||
"uid": event["uid"][0].value,
|
||||
"dtstart": str(event["dtstart"][0].value),
|
||||
"dtend": str(event["dtend"][0].value)
|
||||
}
|
||||
# may or may not be there, idk why. vobject format is really weird
|
||||
for key in ["summary","description","status"]:
|
||||
if key in event:
|
||||
evdata[key] = event[key][0].value
|
||||
return evdata
|
||||
|
||||
|
||||
def generateDateTree(calendars):
|
||||
events = {}
|
||||
for cal in calendars:
|
||||
events_fetched = cal.date_search(start,end)
|
||||
for event in events_fetched:
|
||||
for date in daysOfEvent(event):
|
||||
if not date in events:
|
||||
events[date] = []
|
||||
events[date].append(jsonifyEvent(event))
|
||||
return events
|
||||
|
||||
events = generateDateTree(calendars)
|
||||
|
||||
if args["json"]:
|
||||
print(json.JSONEncoder().encode(events))
|
||||
exit(0)
|
||||
|
||||
# and now we're just generating calendar lines
|
||||
cal_prints = []
|
||||
selected_date = datetime.date(args['year'],args['month'],args['day'])
|
||||
selected_date = date(args['year'],args['month'],args['day'])
|
||||
for year,month in ympairs((args['year'],args['month']),offset,dstart=args['3']):
|
||||
# a function to colorize cells in a more or less generic way
|
||||
def lambdafunc(cell):
|
||||
day = int(cell)
|
||||
if day in events[(year,month)]:
|
||||
event = events[(year,month)][day]
|
||||
uid = event[0]["uid"][0].value.encode()
|
||||
day = date(year,month,int(cell))
|
||||
if str(day) in events:
|
||||
event = events[str(day)]
|
||||
uid = event[0]["uid"].encode()
|
||||
cell = colorize(cell,uid)
|
||||
if datetime.date(year,month,day) == selected_date:
|
||||
if day == selected_date:
|
||||
cell = colorize(cell,"inverse")
|
||||
return cell
|
||||
cal_prints.append(gencal(year,
|
||||
|
|
Loading…
Reference in New Issue