willsonlincake 发表于 2022-4-15 01:43:50

德国大神写的Scribus日历插件

# -*- coding: UTF-8 -*-

"""
VERSION: 0.1    2022
AUTHOR: RASCADINO.
LICENSE: GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.

Scribus Version >= 1.5.8 Mac

Download Scribus 1.5.8 (scribus-devel)
https://sourceforge.net/projects/scribus/files/scribus-devel/1.5.8/

Nutzung:

!!! Das Script wurde nur unter MacOs 12.x getestet.
!!! Zum Verhalten in andern Betriebssystemen kann vom Autor keine Aussage getroffen werden.

Aufruf im Terminal: /Applications/Scribus.app/Contents/MacOS/Scribus -g -ns -py /pfad/zu/deinem/kalendersript.py
Aufruf in Scribus:Menü 'Scrip' -> 'Script ausführen...

Falls Module nicht vorhanden sind, können diese wie folgt installiert werden:
/Applications/Scribus.app/Contents/Frameworks/Python.framework/Versions/3.9/bin/pip3 install modulname

Kalenderbilder:
Bilder numerisch nach den Monaten benennen: 01.jpg, ... 12.jpg
Nur JPGs mit der Erweiterung . jpg
Alle 12 Bilder in einen Ordner speichern

Nach dem Scriptaufruf poppen Dialoge auf mit den Fragen nach:
    - Kalenderformat, DIN A3 oder DIN A2
    - Kalenderjahr
    - Ordner der Kalenderbilder
    - unter welchem Namen soll der Kalender gespeichert werden (gespeichert wird als Scribus *.sla)
    - Speicherort
    - Copyright Inhaber

Achtung!
Das Speichern der PDF-Datei kann je nach Maschine einige Zeit dauern. Wenn sich Scribus von selbst
schließt ist der Vorgang in der Regel abgeschlossen. Etwas Geduld haben!
"""

#imports
import calendar
from calendar import monthrange
import locale
import datetime
from datetime import datetime, timedelta, date
import platform
import pandas as pd
import sys
import time

try:
    import scribus
except ImportError:
    print("Dieses Python-Script läuft nur innerhalb des Scribus scripting interface.")
    print("Aufruf via Command Line oder direkt aus Scribus Menü Script -> Script ausführen..!")
    sys.exit(1)

os = platform.system()
if os != "Darwin":
    print("Dein Betriebssystem wird wahrscheinlich nicht unterstützt! Getestet nur nur für MAC OS.")
    scribus.messageBox("OS error", "Dein Betriebssystem wird wahrscheinlich nicht unterstützt! Getestet nur für MAC OS.", scribus.ICON_INFORMATION)
    #sys.exit(1)

todays_date = date.today()
nextYear = int(todays_date.year) + 1

# Dialog-Boxen zur Personalisierung
calFormat      = scribus.valueDialog('Kalenderformat', 'Kalenderformt DIN A3 ODER DIN A2', "A2")
year            = scribus.valueDialog('Kalenderjahr', 'Bitte Kalenderjahr eingeben', str(nextYear))
calName         = scribus.valueDialog('Name Deines Kalenders, ohne Erweiterung', 'Dateiname', 'meinTollerKalender')
copyrightOwner= scribus.valueDialog('Cpyright Inhaber', 'Copyright', 'Max Mustermann')
calImagePath    = scribus.fileDialog('Ordner Deiner Kalenderbilder auswählen', "Bilder", isdir=1)
calPath         = scribus.fileDialog('Ordner auswählen, in dem Dein Kalender gespeichert wird', "Ordner auswählen", isdir=1)
calPathName   = calPath + "/" + calName + ".sla"
year            = int(year)
calImagePath    = calImagePath + "/"

# Parameter
calImageExt   = ".jpg"                                       # Dateierweiterung der Bilder
fontDefault   = "SF Pro Text Ultralight"                     # https://github.com/sahibjotsaggu/San-Francisco-Pro-Fonts/blob/master/SF-Pro-Text-Ultralight.otf
black         = "#282728"                                    # in Scribus anlegen CMYK
cyan            = 'Cyan'
grau            = '#7e7e7e'                                    # in Scribus anlegen CMYK
copyright       = u"\xa9 " + str(year) + " " + copyrightOwner
monat         = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]
jahrZeitAnfang= [["2022", ["2022-03-20", "2022-06-21", "2022-09-23", "2022-12-21"]], ["2023", ["2023-03-20", "2023-06-21", "2023-09-23", "2023-12-21"]], ["2024", ["2024-03-20", "2024-06-20", "2024-09-22", "2024-12-21"]], ["2025", ["2025-03-20", "2025-06-21", "2025-09-22", "2025-12-21"]], ["2026", ["2026-03-20", "2026-06-21", "2026-09-22", "2026-12-21"]], ["2027", ["2027-03-20", "2027-06-21", "2027-09-23", "2027-12-22"]], ["2028", ["2028-03-20", "2028-06-20", "2028-09-23", "2028-12-21"]], ["2029", ["2029-03-20", "2029-06-21", "2029-09-22", "2029-12-21"]], ["2030", ["2030-03-20", "2030-06-21", "2030-09-22", "2030-12-21"]]]

# Ab hier nichts mehr ändern!
###########################################################################################################################################################################
if(calFormat == "A2"):
    print("A2")
    formatB         = 594         # DIN A2 Breite
    formatH         = 420         # DIN A2 Höhe
    datBoxB         = 13
    datBoxH         = 8.5
    datBoxStartX    = 13.6
    datBoxY         = 400.5
    datBoxFontSize= 20
    holBoxX         = 16.8
    holBoxY         = 410.5
    holBoxB         = 400
    holBoxH         = 5
    holFontSize   = 9
    mBoxX         = 488
    mBoxY         = 397.5
    mBoxB         = 90
    mBoxH         = 15
    mBoxFontSize    = 30
    lineBoxStartY   = 397.6
    lineBoxEndY   = 407.1
    lineBoxWidth    = 0.035
    wnTextBoxY      = lineBoxStartY - 1
    wnTextBoxB      = 6
    wnTextBoxH      = 6
    wnTextBoxFontSize = 10
    iBoxX         = 17
    iBoxY         = 17
    iBoxB         = 560
    iBoxH         = 560 / 1.5
    tBoxXstart      = 10
    tBoxB         = 143
    tBoxH         = 143 / 1.5
    tBoxY         = 53
    yBoxX         = 0
    yBoxY         = 364
    yBoxB         = formatB
    yBoxH         = 25
    cBoxX         = 0
    cBoxY         = 386
    cBoxB         = formatB
    cBoxH         = 6
else:
    print("A3")
    formatB         = 420         # DIN A3 Breite
    formatH         = 297         # DIN A3 Höhe
    datBoxB         = 10.5
    datBoxH         = 8.5
    datBoxStartX    = 26
    datBoxY         = 271
    datBoxFontSize= 18
    holBoxX         = 28.25
    holBoxY         = 286
    holBoxB         = 285
    holBoxH         = 5
    holFontSize   = 9
    mBoxX         = 362.25
    mBoxY         = datBoxY
    mBoxB         = 30
    mBoxH         = 8.5
    mBoxFontSize    = 18
    lineBoxStartY   = 267.5
    lineBoxEndY   = 277
    lineBoxWidth    = 0.035
    wnTextBoxY      = lineBoxStartY - 1
    wnTextBoxB      = 6
    wnTextBoxH      = 6
    wnTextBoxFontSize = 10
    iBoxX         = 28.15
    iBoxY         = 17
    iBoxB         = 363.9
    iBoxH         = 242.6
    tBoxXstart      = 10
    tBoxY         = 40
    tBoxB         = 100
    tBoxH         = 100 / 1.5
    yBoxX         = 0
    yBoxY         = 258
    yBoxB         = formatB
    yBoxH         = 25
    cBoxX         = 0
    cBoxY         = 280
    cBoxB         = formatB
    cBoxH         = 6
#sys.exit()
#################################
# functions
#################################

def feiertage(year):
    A = year % 19
    K = year // 100
    M = 15 + (3 * K + 3) // 4 - ( 8 * K + 13) // 25
    D = (19 * A + M) % 30
    S = 2 - (3 * K + 3) // 4
    R = D // 29 + (D // 28 - D // 29) * (A // 11)
    OG = 21 + D + R
    SZ = 7 - (year + year // 4 + S) % 7
    OE = 7 - (OG - SZ) % 7
    OS = (OG + OE)
    if OS > 31:
      os = str(year) + "-04-" + str(OS-31)
      kf = str(year) + "-04-" + str(OS-33)
      om = str(year) + "-04-" + str(OS-30)
    else:
      os = str(year) + "-04-" + str(OS)
      kf = str(year) + "-04-" + str(OS-2)
      om = str(year) + "-04-" + str(OS+1)
    easter = [
      ,
      ,
      
    ]
    oss = easter.split('-')
    himf = datetime(int(oss), int(oss), int(oss)) + timedelta(days = 40)
    himf = str(himf).split(' ')
    easter.append(, "Christi Himmelfahrt", 1])
    pfso = datetime(int(oss), int(oss), int(oss)) + timedelta(days = 49)
    pfso = str(pfso).split(' ')
    easter.append(, "Pfingstsonntag", 1])
    pfmo = datetime(int(oss), int(oss), int(oss)) + timedelta(days = 50)
    pfmo = str(pfmo).split(' ')
    easter.append(, "Pfingstmontag", 0])
    frln = datetime(int(oss), int(oss), int(oss)) + timedelta(days = 60)
    frln = str(frln).split(' ')
    easter.append(, "Fronleichnam", 0])
    rosm = datetime(int(oss), int(oss), int(oss)) - timedelta(days = 48)
    rosm = str(rosm).split(' ')
    easter.append(, "Rosenmontag", 0])
    sont = datetime(year, 12, 24).weekday()
    if sont != 6:         # 24.12. ist kein Sonntag
      diff4 = sont + 1
      adv4 = datetime(year, 12, 24) - timedelta(int(diff4))
      adv4 = str(adv4).split(' ')
      diff3 = diff4 + 7
      adv3 = datetime(year, 12, 24) - timedelta(int(diff3))
      adv3 = str(adv3).split(' ')
      diff2 = diff4 + 14
      adv2 = datetime(year, 12, 24) - timedelta(int(diff2))
      adv2 = str(adv2).split(' ')
      diff1 = diff4 + 21
      adv1 = datetime(year, 12, 24) - timedelta(int(diff1))
      adv1 = str(adv1).split(' ')
    else:                   # 24.12. ist Sonntag
      adv4 = str(year) + '-12-24'
      adv3 = datetime(year, 12, 24) - timedelta(7)
      adv3 = str(adv3).split(' ')
      adv2 = datetime(year, 12, 24) - timedelta(14)
      adv2 = str(adv2).split(' ')
      adv1 = datetime(year, 12, 24) - timedelta(21)
      adv1 = str(adv1).split(' ')
    easter.append(, "1. Advent", 0])
    easter.append(, "2. Advent", 0])
    easter.append(, "3. Advent", 0])
    easter.append(, "4. Advent", 0])
    easter.append()
    easter.append()
    easter.append()
    easter.append()
    easter.append()
    easter.append()
    easter.append()
    easter.append()
    for x in jahrZeitAnfang:
      if x == str(year):
            easter.append(, "Frühlingsanfang", 0])
            easter.append(, "Sommeranfang", 0])
            easter.append(, "Herbstanfang", 0])
            easter.append(, "Winteranfang", 0])
    return(easter)

def daysInMonth(year):
    dim = []
    for m in range(1, 13):
      dim.append(monthrange(year, m))
    return (dim)

def compCal(year):
    cal = []
    m = 1
    dpm = daysInMonth(year)
    for d in dpm:
      n = m - 1
      cal.append()
      for r in range(1, d + 1):
            dat = str(year) + "-" + str(m).zfill(2) + "-" + str(r).zfill(2)   # Datum
            ts = pd.Timestamp(dat)
            dna = ts.dayofweek                                                # Wochentag
            d1 = ""
            d2 = 0
            d3 = ""
            for f in feiertage(year):                                           # Feiertag?
                if str(dat) == str(f):
                  d1 = str(f)
                  d2 = str(f)
            ts = pd.Timestamp(int(year), int(m), int(r))
            d3 = str(ts.week).zfill(2)
            cal.append()                               # , ...], ...
      m += 1
    return(cal)

############################
# Scribus Code
############################

def baueKalender(year):
    calenda = compCal(year)
    #print(calenda)
    #sys.exit()
    scribus.newDocument((formatH, formatB), (0, 0, 0, 0), scribus.LANDSCAPE, 1, scribus.UNIT_MILLIMETERS, scribus.PAGE_1, 12, 1)
    scribus.createLayer("Bilder")
    scribus.createLayer("Text")
    for z in range(0, 11):
      scribus.newPage(-1)

    for p in range(scribus.pageCount()):
      m=p + 1
      print("Baue Blatt " + str(m))
      scribus.gotoPage(m)
      fText = ""
      for n in range(len(calenda)):
            if len(str(calenda)) > 2:
                if len(str(calenda)) > 0:
                  part = str(calenda).split('-')
                  fDat = part + "." + part + ". "
                  fText = fText + str(fDat) + str(calenda) + " " + u"\xb7 "
                dat = str(calenda).split("-")
                if n > 1:
                  datBoxX = (datBoxB * (n - 1)) + datBoxStartX
                else:
                  datBoxX = datBoxStartX
                dBox = scribus.createText(datBoxX, datBoxY, datBoxB, datBoxH)
                scribus.setText(dat, dBox)
                scribus.setFont(fontDefault, dBox)
                scribus.setFontSize(datBoxFontSize, dBox)
                scribus.setTextAlignment(scribus.ALIGN_CENTERED, dBox)
                scribus.sendToLayer("Text" , dBox)
                if int(calenda) > 5 or int(calenda) > 0:
                  color = cyan
                else:
                  color = black
                scribus.setTextColor(color, dBox)
                #Wochennummer
                if int(calenda) < 1:
                  # Trennlinie
                  wnLine = scribus.createLine(datBoxX, lineBoxStartY, datBoxX, lineBoxEndY)
                  scribus.setLineWidth(lineBoxWidth, wnLine)
                  scribus.setLineColor(grau, wnLine)
                  scribus.sendToLayer("Text", wnLine)
                  # Wochennummer
                  wnTxt = scribus.createText(datBoxX + 1, wnTextBoxY, wnTextBoxB, wnTextBoxH)
                  scribus.setText(str(calenda), wnTxt)
                  scribus.setFont(fontDefault, wnTxt)
                  scribus.setFontSize(wnTextBoxFontSize, wnTxt)
                  scribus.setTextColor(grau, wnTxt)
                  scribus.setTextAlignment(scribus.ALIGN_CENTERED, wnTxt)
                  scribus.sendToLayer("Text", wnTxt)
      # Zeile Feiertage
      fText = fText[:-3]
      fBox = scribus.createText(holBoxX, holBoxY, holBoxB, holBoxH)
      scribus.setText(fText, fBox)
      scribus.setFont(fontDefault, fBox)
      scribus.setFontSize(holFontSize, fBox)
      scribus.setTextColor(grau, fBox)
      scribus.setTextAlignment(scribus.ALIGN_LEFT, fBox)
      # Zeile Monat Jahr
      mBox = scribus.createText(mBoxX, mBoxY, mBoxB, mBoxH)
      if calFormat == "A2":
            scribus.setText(monat + " " + u"\xb7" + " " + str(year), mBox)
      else:
            scribus.setText(str(m).zfill(2) + " " + u"\xb7" + " " + str(year), mBox)
      scribus.setFont(fontDefault, mBox)
      scribus.setFontSize(mBoxFontSize, mBox)
      scribus.setTextColor(black, mBox)
      scribus.setTextAlignment(scribus.ALIGN_RIGHT, mBox)
      # Bilder
      iBox = scribus.createImage(iBoxX, iBoxY, iBoxB, iBoxH)
      imgName = str(m).zfill(2) + str(calImageExt)
      scribus.loadImage( calImagePath + imgName, iBox)
      scribus.setScaleImageToFrame(1,1,iBox)
      scribus.sendToLayer("Bilder" , iBox)
    # Deckblatt
    print("Baue Deckblatt")
    scribus.newPage(1)
    # Hintergrund
    tBackGroud = scribus.createRect(10, tBoxY, tBoxB * 4, tBoxH * 3)
    scribus.setFillColor(grau, tBackGroud)
    scribus.sendToLayer("Bilder", tBackGroud)
    scribus.selectObject(tBackGroud)
    scribus.moveSelectionToBack()
    scribus.deselectAll()
    # Bilder
    for i in range(0, 12):
      if i < 4:                           # 1. Reihe Bilder
            xt = tBoxXstart + i * tBoxB
            yt = tBoxY
      elif i > 3 and i < 8:               # 2. Reihe Bilder
            xt = 10 + (i - 4) * tBoxB
            yt = tBoxY + tBoxH
      elif i > 7:                         # 3. Reihe Bilder
            xt = 10 + (i - 8) * tBoxB
            yt = tBoxY + 2 * tBoxH
      z = i + 1
      iBox = scribus.createImage(xt, yt, tBoxB, tBoxH)
      tName = str(z).zfill(2) + str(calImageExt)
      scribus.loadImage( calImagePath + tName, iBox)
      scribus.setScaleImageToFrame(1,0,iBox)
      scribus.setScaleImageToFrame(0,1,iBox)
      scribus.sendToLayer("Bilder" , iBox)
    # Jahreszahl
    yBox = scribus.createText(yBoxX, yBoxY, yBoxB, yBoxH)
    scribus.setText(str(year), yBox)
    scribus.setFont(fontDefault, yBox)
    scribus.setFontSize(50, yBox)
    scribus.setTextColor(black, yBox)
    scribus.setTextAlignment(scribus.ALIGN_CENTERED, yBox)
    # copyright
    cBox = scribus.createText(cBoxX, cBoxY, cBoxB, cBoxH)
    scribus.setText(copyright, cBox)
    scribus.setFont(fontDefault, cBox)
    scribus.setFontSize(12, cBox)
    scribus.setTextColor(black, cBox)
    scribus.setTextAlignment(scribus.ALIGN_CENTERED, cBox)
    # Dokument speichern (.sla)
    scribus.saveDocAs(calPathName)
    # PDF
    pdf = scribus.PDFfile()
    pdf.file = calPath + "/" + calName + ".pdf"
    pdf.save()

# Script Auftruf
######################################################
def main():
    """ Application/Dialog loop with Scribus sauce around """
    try:
      scribus.statusMessage('Running script...')
      scribus.progressReset()
      app = baueKalender(year)
    finally:
      if scribus.haveDoc() > 0:
            scribus.redrawAll()
      scribus.statusMessage('Done.')
      scribus.progressReset()

if __name__ == '__main__':
    main()

页: [1]
查看完整版本: 德国大神写的Scribus日历插件