From 369b3655da290f723a7acd3e026b211224b10381 Mon Sep 17 00:00:00 2001 From: Thomas Vogl Date: Sat, 17 Dec 2022 00:35:20 +0100 Subject: [PATCH] ... --- calendar_main.py | 30 ++++++--- feiertage_api.py | 52 +++++++++++++++ ferien_api.py | 51 +++++++++++++++ scribus_calendar/base_objects.py | 96 ++++++++++++++++++++++++---- scribus_calendar/calendars.py | 5 +- scribus_calendar/config_parser.py | 12 ++-- scribus_calendar/monthly_objects.py | 98 +++++++++++++++++++++++++++-- test.json | 64 ++++++------------- 8 files changed, 333 insertions(+), 75 deletions(-) create mode 100644 feiertage_api.py create mode 100644 ferien_api.py diff --git a/calendar_main.py b/calendar_main.py index d9519a5..748bea8 100644 --- a/calendar_main.py +++ b/calendar_main.py @@ -4,7 +4,6 @@ import sys import os - try: import scribus except ImportError: @@ -15,6 +14,10 @@ except ImportError: from scribus_calendar.config_parser import ConfigParser from scribus_calendar.calendars import MonthlyCalendar from scribus_calendar.monthly_objects import * +from scribus_calendar.base_objects import UserDefinedObjects + +from feiertage_api import FeiertageApi +from ferien_api import FerienApi def class_from_name(className): @@ -25,9 +28,19 @@ def main(argv): objects = [] #compute config file path - thisDir = os.path.dirname(argv[0]) - defaultConfigFile = os.path.join(thisDir, "test.json") - configParser = ConfigParser(defaultConfigFile) + thisDir = os.getcwd() + defaultConfigFile = scribus.fileDialog("calender config :: open file", "*.json") + + try: + configParser = ConfigParser(defaultConfigFile) + except Exception as e: + raise Exception(defaultConfigFile) + + feiertageApi = FeiertageApi(configParser.settings["year"], configParser.settings["bundesland"]) + ferienApi = FerienApi(configParser.settings["year"], configParser.settings["bundesland"]) + configParser.addEvents(feiertageApi.get()) + configParser.addEvents(ferienApi.get()) + #create objects from config file @@ -35,10 +48,13 @@ def main(argv): for module in strListModuleObjects: obj = class_from_name(module)() obj.configure(configParser) - objects.append(obj) + + noglobal = getattr(obj, "noGlobal", False) + if noglobal == False: + objects.append(obj) #create calendar object from defined class in config - calendar = class_from_name(configParser.settings["calendarClass"])(objects, configParser.settings["year"]) + calendar = class_from_name(configParser.settings["calendarClass"])(objects, configParser.settings["year"], configParser.settings["numMonths"]) calendar.createStyles() calendar.createLayers() @@ -75,4 +91,4 @@ def main_wrapper(argv): # It only runs main() if being run as a script. This permits you to import your script # and control it manually for debugging. if __name__ == '__main__': - main_wrapper(sys.argv) \ No newline at end of file + main_wrapper(sys.argv) diff --git a/feiertage_api.py b/feiertage_api.py new file mode 100644 index 0000000..722eec6 --- /dev/null +++ b/feiertage_api.py @@ -0,0 +1,52 @@ +import copy +import json +import datetime +import httplib +import re +class FeiertageApi(object): + def __init__(self, jahr, nur_land): + self.base_url = 'feiertage-api.de' + self.jahr = jahr + self.nur_land = nur_land + self.nur_daten = None + pass + + def get(self): + requestUrl = "/api/?jahr={}".format(self.jahr) + + if self.nur_daten is not None: + requestUrl += "&nur_daten={}".format(self.nur_daten) + + if self.nur_land is not None: + requestUrl += "&nur_land={}".format(self.nur_land) + + conn = httplib.HTTPSConnection(self.base_url) + conn.request('GET',requestUrl) + response = conn.getresponse() + body = response.read() + conn.close() + return self.__format(json.loads(body)) + + def __convert_date(self, strDate): + + m = re.match(r"^([0-9]+)-([0-9]+)-([0-9]+)$", strDate) + + return "{}-{}".format(m.group(2), m.group(3)) + + def __format(self, data): + listFeiertage = list() + for k,v in data.items(): + listFeiertage.append({ + "name": k, + "from": self.__convert_date(v["datum"]), + "to": self.__convert_date(v["datum"]), + "hint": v["hinweis"] + }) + + return { + "bankHolidays": { + "name": "Feiertage ({})".format(self.nur_daten), + "dates": listFeiertage + } + } + diff --git a/ferien_api.py b/ferien_api.py new file mode 100644 index 0000000..2b9ffd0 --- /dev/null +++ b/ferien_api.py @@ -0,0 +1,51 @@ +import copy +import json +import datetime +import httplib +import re + +class FerienApi(object): + def __init__(self, jahr, nur_land): + self.base_url = 'ferien-api.de' + self.jahr = jahr + self.nur_land = nur_land + self.nur_daten = None + pass + + def get(self): + requestUrl = "/api/v1/holidays/{}".format(self.nur_land) + + conn = httplib.HTTPSConnection(self.base_url) + conn.request('GET',requestUrl) + response = conn.getresponse() + body = response.read() + conn.close() + return self.__format(json.loads(body)) + + def __convert_date(self, strDate): + m = re.match(r'^([0-9]{4})-([0-9]{2})-([0-9]{2})T.+Z$', strDate) + return "{}-{}-{}".format(m.group(1), m.group(2), m.group(3)) + + def __format(self, data): + listFerien = list() + for d in data: + d["name"] = d["name"][0].upper() + d["name"][1:] + listFerien.append({ + "name": d["name"], + "from": self.__convert_date(d["start"]), + "to": self.__convert_date(d["end"]), + "hinweis": "" + }) + + return { + "schoolHolidays": { + "name": "Schulferien ({})".format(self.nur_land), + "dates": listFerien + } + } + + + +if __name__ == "__main__": + api = FerienApi(2021, "BY") + print(json.dumps(api.get(), indent=4)) \ No newline at end of file diff --git a/scribus_calendar/base_objects.py b/scribus_calendar/base_objects.py index 999a9a4..903f32c 100644 --- a/scribus_calendar/base_objects.py +++ b/scribus_calendar/base_objects.py @@ -2,13 +2,16 @@ import scribus import datetime import calendar +import re + +class Constants(object): + DefaultFont = "" class ScribusCalendar(object): def __init__(self, objects, year): self.objects = objects self.year = year - def createStyles(self): existing_styles = scribus.getAllStyles() for obj in self.objects: @@ -39,14 +42,15 @@ class ScribusCalendar(object): class CalendarObject(object): def __init__(self, name): self.name = name - + self.noStub = False self.position = (0,0) self.size = (100,100) - self.paragraphStyle = "DefaultCalenderParagraphStyle" self.charStyle = "DefaultCalenderCharStyle" self.layer = "CalendarLayer" + self.defaultFontSize = 8 + self.configParser = None self.date = datetime.date.today() @@ -63,23 +67,47 @@ class CalendarObject(object): existingLayers.append(self.layer) def createStyles(self, existingStyles): - if self.charStyle not in existingStyles: - scribus.createCharStyle(self.charStyle, "DejaVu Sans", 8) - existingStyles.append(self.charStyle) - - if self.paragraphStyle not in existingStyles: - scribus.createParagraphStyle(self.paragraphStyle ,1,0,0,0,0,0,0,0,0,0,0,self.charStyle) - existingStyles.append(self.paragraphStyle) + charStyles = self.charStyle + paragraphStyles = self.paragraphStyle + defaultFontSizes = self.defaultFontSize + + if not type(self.charStyle) is list: + charStyles = [ self.charStyle ] + + if not type(self.paragraphStyle) is list: + paragraphStyles = [ self.paragraphStyle ] + + if not type(self.defaultFontSize) is list: + defaultFontSizes = [ self.defaultFontSize ] + + + + for i in range(0,len(charStyles)): + + if charStyles[i] not in existingStyles: + scribus.createCharStyle(charStyles[i], Constants.DefaultFont, defaultFontSizes[i]) + existingStyles.append(charStyles[i]) + + if paragraphStyles[i] not in existingStyles: + scribus.createParagraphStyle(paragraphStyles[i] ,1,0,0,0,0,0,0,0,0,0,0,charStyles[i]) + existingStyles.append(paragraphStyles[i]) def plotStub(self): + if self.noStub == True: + return False + if not scribus.objectExists(self.name): scribus.createText(self.position[0],self.position[1], self.size[0],self.size[1], self.name) + scribus.setStyle(self.paragraphStyle, self.name) scribus.insertText(self.name, 0, self.name) scribus.sentToLayer(self.layer, self.name) return True return False def readFromStub(self): + if self.noStub == True: + return + p = scribus.getPosition(self.name) s = scribus.getSize(self.name) @@ -88,10 +116,10 @@ class CalendarObject(object): def plotObject(self): pass - def configure(self, configParser): className = self.__class__.__name__ settings = dict() + self.configParser = configParser try: settings = configParser.modules[className] @@ -108,6 +136,8 @@ class WeekDayNameObject(CalendarObject): def __init__(self, name): CalendarObject.__init__(self,name) self.weekday = datetime.date.today().weekday() + self.paragraphStyle = "WeekDayNameParagraphStyle" + self.charStyle = "WeekDayNameCharStyle" def getName(self): return calendar.day_name[self.date.weekday()] @@ -119,6 +149,8 @@ class WeekNameObject(CalendarObject): def __init__(self, name): CalendarObject.__init__(self,name) self.weeknumber = 1 + self.paragraphStyle = "WeekNameParagraphStyle" + self.charStyle = "WeekNameCharStyle" def setDate(self, date): CalendarObject.setDate(self, date) @@ -131,6 +163,48 @@ class WeekNameObject(CalendarObject): def getNameAbbrev(self): return self.getName() +class MonthNameObject(CalendarObject): + def __init__(self, name): + CalendarObject.__init__(self, name) + self.paragraphStyle = "MonthNameParagraphStyle" + self.charStyle = "MonthNameCharStyle" + + def getMonthName(self): + return calendar.month_name[self.date.month] + + +class UserDefinedObjects(CalendarObject): + def __init__(self): + CalendarObject.__init__(self, "UserDefinedObjects") + self.layer = "UserDefinedObjects" + self.noStub = True + + def plotObject(self): + layers = scribus.getLayers() + currentPage = scribus.currentPage() + + scribus.gotoPage(1) + objects = scribus.getAllObjects() + + for obj in objects: + m = re.match(r'^(.+)__(.+)$', obj) + if m is None: + continue + + layerName = m.group(1) + + if not layerName in layers: + scribus.createLayer(layerName) + + scribus.gotoPage(1) + scribus.copyObject(obj) + scribus.gotoPage(currentPage) + scribus.setActiveLayer(layerName) + scribus.pasteObject(obj) + + + + diff --git a/scribus_calendar/calendars.py b/scribus_calendar/calendars.py index ae646c1..a56129e 100644 --- a/scribus_calendar/calendars.py +++ b/scribus_calendar/calendars.py @@ -3,8 +3,9 @@ import datetime from .base_objects import ScribusCalendar class MonthlyCalendar(ScribusCalendar): - def __init__(self, objects, year): + def __init__(self, objects, year, numMonths): ScribusCalendar.__init__(self, objects, year) + self.numMonths = numMonths def plotObjects(self): @@ -14,7 +15,7 @@ class MonthlyCalendar(ScribusCalendar): scribus.deletePage(i) - for i in range(1,2): + for i in range(1,self.numMonths + 1): scribus.newPage(-1) for obj in self.objects: obj.setDate(datetime.date(self.year, i, 1)) diff --git a/scribus_calendar/config_parser.py b/scribus_calendar/config_parser.py index 8aa6468..dff229a 100644 --- a/scribus_calendar/config_parser.py +++ b/scribus_calendar/config_parser.py @@ -5,11 +5,12 @@ class ConfigParser(object): def __init__(self, filename): with open(filename, "r") as f: self.jsonContent = json.load(f) + self.events = dict() self.settings = dict() self.__parseSettings() - self.__parseEvents() + self.addEvents(self.jsonContent["events"]) self.__parseModuleSettings() def __parseModuleSettings(self): @@ -33,13 +34,16 @@ class ConfigParser(object): return datetime.date(year=self.settings["year"], month=int(d[0]), day=int(d[1])) - def __parseEvents(self): - self.events = self.jsonContent["events"] - for key, val in self.events.items(): + def addEvents(self, jsonContent): + for key, val in jsonContent.items(): dates = val["dates"] for ev in dates: self.__parseDateRange(ev) + self.events.update(jsonContent) + + + def printEvents(self): for key, val in self.events.items(): dates = val["dates"] diff --git a/scribus_calendar/monthly_objects.py b/scribus_calendar/monthly_objects.py index 958a73d..d91434b 100644 --- a/scribus_calendar/monthly_objects.py +++ b/scribus_calendar/monthly_objects.py @@ -1,4 +1,4 @@ -from .base_objects import MonthlyCalendarObject, WeekDayNameObject, DailyCalendarObject, WeekNameObject +from .base_objects import MonthlyCalendarObject, WeekDayNameObject, DailyCalendarObject, WeekNameObject, MonthNameObject from .calendar_helpers import MonthCalendarMatrix import calendar import math @@ -13,41 +13,114 @@ def class_from_name(className): class SimpleWeekDayNameObject(WeekDayNameObject): def __init__(self): WeekDayNameObject.__init__(self, "SimpleWeekDayNameObject") + self.noStub = True def plotObject(self): textBox = scribus.createText(self.position[0],self.position[1], self.size[0],self.size[1]) + scribus.setStyle(self.paragraphStyle, textBox ) scribus.insertText(self.getNameAbbrev(), 0, textBox ) scribus.sentToLayer(self.layer, textBox) +class SimpleMonthNameObject(MonthNameObject): + def __init__(self): + MonthNameObject.__init__(self, "SimpleMonthNameObject") + + def plotObject(self): + textBox = scribus.createText(self.position[0],self.position[1], self.size[0],self.size[1]) + scribus.setStyle(self.paragraphStyle, textBox ) + scribus.insertText(self.getMonthName(), 0, textBox ) + scribus.sentToLayer(self.layer, textBox) + class SimpleWeekNameObject(WeekNameObject): def __init__(self): WeekNameObject.__init__(self, "SimpleWeekNameObject") + self.noStub = True def plotObject(self): textBox = scribus.createText(self.position[0],self.position[1], self.size[0],self.size[1]) + scribus.setStyle(self.paragraphStyle, textBox ) scribus.insertText(self.getNameAbbrev(), 0, textBox ) scribus.sentToLayer(self.layer, textBox) + class FormattedDayObject(DailyCalendarObject): def __init__(self): DailyCalendarObject.__init__(self,"FormattedDayObject") + self.noStub = True - self.paragraphStyle = "S" + self.paragraphStyle = [ + 'DayLetterParagraphStyle', + 'DayLetterHighlightParagraphStyle', + 'EventParagraphStyle'] + + self.charStyle = [ + 'DayLetterCharStyle', + 'DayLetterHighlightCharStyle', + 'EventCharStyle'] + + self.defaultFontSize = [ 8, 8, 4] def plotObject(self): if self.isActive: - textBox = scribus.createText(self.position[0],self.position[1], self.size[0],self.size[1]) + heightEventBox = self.size[1] * self.heightEventbox + heightLetterBox = self.size[1] * ( 1 - self.heightEventbox ) + + widthHolidaybox = self.size[0] * self.widthHolidaybox + widthLetterbox = self.size[0] * ( 1 - self.widthHolidaybox) + + dayLetterBox = [ self.position[0] + ,self.position[1] + ,widthLetterbox + ,heightLetterBox ] + + eventNameBox = [ self.position[0] + ,self.position[1] + heightLetterBox + ,self.size[0] + ,heightEventBox ] + + holidayBox = [ self.position[0] + widthLetterbox + ,self.position[1] + ,widthHolidaybox + ,heightLetterBox ] + + bankHolidayEvent = self.configParser.getEvent(self.date, "bankHolidays") + schoolHolidayEvent = self.configParser.getEvent(self.date, "schoolHolidays") + + dayLetterStyle = self.paragraphStyle[0] + if bankHolidayEvent is not None: + if ( bankHolidayEvent[1]["hint"] == "" ): + dayLetterStyle = self.paragraphStyle[1] + + eventNameTextBox = scribus.createText(*eventNameBox) + scribus.insertText(bankHolidayEvent[1]["name"], 0, eventNameTextBox ) + scribus.setStyle(self.paragraphStyle[2], eventNameTextBox) + scribus.sentToLayer(self.layer, eventNameTextBox) + + if schoolHolidayEvent is not None: + holidayTextbox = scribus.createText(*holidayBox) + scribus.insertText("F", 0, holidayTextbox ) + scribus.setStyle(self.paragraphStyle[2], holidayTextbox) + scribus.sentToLayer(self.layer, holidayTextbox) + + textBox = scribus.createText(*dayLetterBox) + scribus.setStyle(dayLetterStyle, textBox ) scribus.insertText(self.getName(), 0, textBox ) scribus.sentToLayer(self.layer, textBox) + + + class DayGridObject(DailyCalendarObject): def __init__(self): DailyCalendarObject.__init__(self,"DayGridObject") + self.noStub = True + def plotObject(self): if self.isActive: textBox = scribus.createText(self.position[0],self.position[1], self.size[0],self.size[1]) + scribus.setStyle(self.paragraphStyle, textBox ) scribus.insertText(self.getName(), 0, textBox ) scribus.sentToLayer(self.layer, textBox) @@ -66,6 +139,7 @@ class MonthlyGrid(MonthlyCalendarObject): self.calendarWeekClass = None self.weekDayClass = None self.dayClass = None + self.monthNameClass = None self.createdObjects = [] @@ -83,6 +157,15 @@ class MonthlyGrid(MonthlyCalendarObject): self.scaleFactor[0] = self.size[0] / unitsX self.scaleFactor[1] = self.size[1] / unitsY + def createStyles(self, existing_styles): + self.initSubObjects() + + MonthlyCalendarObject.createStyles(self, existing_styles) + + self.weekDayClass().createStyles(existing_styles) + self.dayClass().createStyles(existing_styles) + self.calendarWeekClass().createStyles(existing_styles) + def setDate(self, date): MonthlyCalendarObject.setDate(self, date) if self.oneLineOnly: @@ -101,11 +184,11 @@ class MonthlyGrid(MonthlyCalendarObject): def plotObject(self): self.createObjects() - for obj in self.createdObjects: obj.plotObject() - def createObjects(self): + + def initSubObjects(self): if type(self.weekDayClass) == unicode : self.weekDayClass = class_from_name(self.weekDayClass) @@ -115,6 +198,10 @@ class MonthlyGrid(MonthlyCalendarObject): if type(self.calendarWeekClass) == unicode: self.calendarWeekClass = class_from_name(self.calendarWeekClass) + + def createObjects(self): + self.initSubObjects() + self.createdObjects = [] w = self.position[0] h = self.position[1] @@ -147,6 +234,7 @@ class MonthlyGrid(MonthlyCalendarObject): self.createdObjects.append(calendarWeekObj) dailyObj = self.dayClass() + dailyObj.configure(self.configParser) dailyObj.setDate(i[j]) dailyObj.setActive(i[j].month == self.date.month) diff --git a/test.json b/test.json index 8776a77..92baeb7 100644 --- a/test.json +++ b/test.json @@ -1,18 +1,30 @@ { "settings": { - "year": 2020, - "calendarClass": "MonthlyCalendar" + "year": 2021, + "bundesland": "BY", + "calendarClass": "MonthlyCalendar", + "numMonths": 12 }, "modules": { "MonthlyGrid": { "numberOfWeeksPerLine": 1, - "oneLineOnly": true, - "heightColWeekNumber": 1.0, - "widthRowWeekName": 1.0, + "oneLineOnly": false, + "heightColWeekNumber": 0.4, + "widthRowWeekName": 0.4, "sizeCellDay": [1.0, 1.0], "calendarWeekClass": "SimpleWeekNameObject", "weekDayClass": "SimpleWeekDayNameObject", - "dayClass": "DayGridObject" + "dayClass": "FormattedDayObject", + "monthNameClass": "SimpleMonthNameObject" + }, + "SimpleMonthNameObject": { + }, + "UserDefinedObjects": { + }, + "FormattedDayObject": { + "heightEventbox": 0.5, + "widthHolidaybox": 0.5, + "noGlobal": true } }, "events": { @@ -24,31 +36,6 @@ "paragraphStyle": "FeiertageParagraphStyle" }, "dates": [ - { - "from": "01-01", - "to": "01-01", - "name": "Neujahr" - }, - { - "from": "10-03", - "to": "10-03", - "name": "Tag der deutschen Einheit" - }, - { - "from": "12-24", - "to": "12-24", - "name": "Heilig Abend" - }, - { - "from": "12-25", - "to": "12-25", - "name": "1. Weihnachtsfeiertag" - }, - { - "from": "12-26", - "to": "12-26", - "name": "2. Weihnachtsfeiertag" - } ] }, "birthdays": { @@ -59,26 +46,11 @@ "paragraphStyle": "FeiertageParagraphStyle" }, "dates": [ - { - "from": "2020-12-30", - "to": "2020-12-30", - "name": "Geburtstag Papa" - }, - { - "from": "2020-11-08", - "to": "2020-11-08", - "name": "Geburtstag Mama" - } ] }, "schoolHolidays": { "name": "Schulferien", "dates": [ - { - "name": "Weihnachtsferien", - "from": "2020-12-21", - "to": "2021-01-07" - } ] } }