This commit is contained in:
Dennis Kerschus
2023-06-13 13:19:05 +02:00
parent c3fcce1527
commit 7c6b05710c
34 changed files with 130185 additions and 0 deletions
@@ -0,0 +1,164 @@
/* -*- indent-tabs-mode: nil; tab-width: 4; -*- */
/* Greenlet object interface */
#ifndef Py_GREENLETOBJECT_H
#define Py_GREENLETOBJECT_H
#include <Python.h>
#ifdef __cplusplus
extern "C" {
#endif
/* This is deprecated and undocumented. It does not change. */
#define GREENLET_VERSION "1.0.0"
#ifndef GREENLET_MODULE
#define implementation_ptr_t void*
#endif
typedef struct _greenlet {
PyObject_HEAD
PyObject* weakreflist;
PyObject* dict;
implementation_ptr_t pimpl;
} PyGreenlet;
#define PyGreenlet_Check(op) (op && PyObject_TypeCheck(op, &PyGreenlet_Type))
/* C API functions */
/* Total number of symbols that are exported */
#define PyGreenlet_API_pointers 12
#define PyGreenlet_Type_NUM 0
#define PyExc_GreenletError_NUM 1
#define PyExc_GreenletExit_NUM 2
#define PyGreenlet_New_NUM 3
#define PyGreenlet_GetCurrent_NUM 4
#define PyGreenlet_Throw_NUM 5
#define PyGreenlet_Switch_NUM 6
#define PyGreenlet_SetParent_NUM 7
#define PyGreenlet_MAIN_NUM 8
#define PyGreenlet_STARTED_NUM 9
#define PyGreenlet_ACTIVE_NUM 10
#define PyGreenlet_GET_PARENT_NUM 11
#ifndef GREENLET_MODULE
/* This section is used by modules that uses the greenlet C API */
static void** _PyGreenlet_API = NULL;
# define PyGreenlet_Type \
(*(PyTypeObject*)_PyGreenlet_API[PyGreenlet_Type_NUM])
# define PyExc_GreenletError \
((PyObject*)_PyGreenlet_API[PyExc_GreenletError_NUM])
# define PyExc_GreenletExit \
((PyObject*)_PyGreenlet_API[PyExc_GreenletExit_NUM])
/*
* PyGreenlet_New(PyObject *args)
*
* greenlet.greenlet(run, parent=None)
*/
# define PyGreenlet_New \
(*(PyGreenlet * (*)(PyObject * run, PyGreenlet * parent)) \
_PyGreenlet_API[PyGreenlet_New_NUM])
/*
* PyGreenlet_GetCurrent(void)
*
* greenlet.getcurrent()
*/
# define PyGreenlet_GetCurrent \
(*(PyGreenlet * (*)(void)) _PyGreenlet_API[PyGreenlet_GetCurrent_NUM])
/*
* PyGreenlet_Throw(
* PyGreenlet *greenlet,
* PyObject *typ,
* PyObject *val,
* PyObject *tb)
*
* g.throw(...)
*/
# define PyGreenlet_Throw \
(*(PyObject * (*)(PyGreenlet * self, \
PyObject * typ, \
PyObject * val, \
PyObject * tb)) \
_PyGreenlet_API[PyGreenlet_Throw_NUM])
/*
* PyGreenlet_Switch(PyGreenlet *greenlet, PyObject *args)
*
* g.switch(*args, **kwargs)
*/
# define PyGreenlet_Switch \
(*(PyObject * \
(*)(PyGreenlet * greenlet, PyObject * args, PyObject * kwargs)) \
_PyGreenlet_API[PyGreenlet_Switch_NUM])
/*
* PyGreenlet_SetParent(PyObject *greenlet, PyObject *new_parent)
*
* g.parent = new_parent
*/
# define PyGreenlet_SetParent \
(*(int (*)(PyGreenlet * greenlet, PyGreenlet * nparent)) \
_PyGreenlet_API[PyGreenlet_SetParent_NUM])
/*
* PyGreenlet_GetParent(PyObject* greenlet)
*
* return greenlet.parent;
*
* This could return NULL even if there is no exception active.
* If it does not return NULL, you are responsible for decrementing the
* reference count.
*/
# define PyGreenlet_GetParent \
(*(PyGreenlet* (*)(PyGreenlet*)) \
_PyGreenlet_API[PyGreenlet_GET_PARENT_NUM])
/*
* deprecated, undocumented alias.
*/
# define PyGreenlet_GET_PARENT PyGreenlet_GetParent
# define PyGreenlet_MAIN \
(*(int (*)(PyGreenlet*)) \
_PyGreenlet_API[PyGreenlet_MAIN_NUM])
# define PyGreenlet_STARTED \
(*(int (*)(PyGreenlet*)) \
_PyGreenlet_API[PyGreenlet_STARTED_NUM])
# define PyGreenlet_ACTIVE \
(*(int (*)(PyGreenlet*)) \
_PyGreenlet_API[PyGreenlet_ACTIVE_NUM])
/* Macro that imports greenlet and initializes C API */
/* NOTE: This has actually moved to ``greenlet._greenlet._C_API``, but we
keep the older definition to be sure older code that might have a copy of
the header still works. */
# define PyGreenlet_Import() \
{ \
_PyGreenlet_API = (void**)PyCapsule_Import("greenlet._C_API", 0); \
}
#endif /* GREENLET_MODULE */
#ifdef __cplusplus
}
#endif
#endif /* !Py_GREENLETOBJECT_H */
+5
View File
@@ -0,0 +1,5 @@
home = C:\Python311
include-system-site-packages = false
version = 3.11.4
executable = C:\Python311\python.exe
command = C:\Python311\python.exe -m venv --upgrade C:\users\denker\Documents\udvikling\Python\FlowAnalyser\.venv
+26
View File
@@ -0,0 +1,26 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Flask",
"type": "python",
"request": "launch",
"module": "flask",
"env": {
"FLASK_APP": "FlowAnalyserMain.py",
"FLASK_DEBUG": "1"
},
"args": [
"run",
"--no-debugger",
"--no-reload"
],
"jinja": true,
"justMyCode": true
}
]
}
+15
View File
@@ -0,0 +1,15 @@
from inn import getEngine
import markdown
def test():
#engine = getEngine()
text = "# Title"+"\n"
text+= "~~~mermaid\n"
text+= "gantt\n"
text+="~~~"
html=markdown.markdown(text, extensions=['md_mermaid'])
print(html)
return html
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+4
View File
@@ -0,0 +1,4 @@
server = 'bi-dsa-udv\dsa' # to
database = 'udv_denker'
username = 'admindenker'
password = 'biadmin#kode4rmO1'
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

+17
View File
@@ -0,0 +1,17 @@
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import Session,registry
from sqlalchemy import sql,Table,select,MetaData
import urllib
def getEngine(database):
server = 'bi-dsa-udv\dsa' # to specify an alternate port
username = 'admindenker'
password = 'biadmin#kode4rm2'
connection_string = "DRIVER={SQL Server};Database="+database+";SERVER="+server
connection_string = urllib.parse.quote_plus(connection_string)
connection_string = "mssql+pyodbc:///?odbc_connect=%s" % connection_string
engine = create_engine(connection_string, echo = True)
return engine
BIN
View File
Binary file not shown.
+346
View File
@@ -0,0 +1,346 @@
/* Flowchart variables */
/* Sequence Diagram variables */
/* Gantt chart variables */
div.mermaid svg
{
display: block;
margin-right: auto;
margin-left: auto;
}
.mermaid .label
{
color: #333;
}
div.mermaid .node rect,
div.mermaid .node circle,
div.mermaid .node ellipse,
div.mermaid .node polygon
{
fill: #ececff;
stroke: #ccf;
stroke-width: 1px;
}
div.mermaid .edgePath .path
{
stroke: #333;
}
div.mermaid .edgeLabel
{
background-color: #e8e8e8;
}
div.mermaid .cluster rect
{
fill: #ffffde !important;
rx: 4 !important;
stroke: #aa3 !important;
stroke-width: 1px !important;
}
div.mermaid .cluster text
{
fill: #333;
}
div.mermaid .actor
{
stroke: #ccf;
fill: #ececff;
}
div.mermaid text.actor
{
fill: black;
stroke: none;
}
div.mermaid .actor-line
{
stroke: grey;
}
div.mermaid .messageLine0
{
stroke-width: 1.5;
stroke-dasharray: '2 2';
marker-end: 'url(#arrowhead)';
stroke: #333;
}
div.mermaid .messageLine1
{
stroke-width: 1.5;
stroke-dasharray: '2 2';
stroke: #333;
}
#arrowhead
{
fill: #333;
}
#crosshead path
{
fill: #333 !important;
stroke: #333 !important;
}
div.mermaid .messageText
{
fill: #333;
stroke: none;
}
div.mermaid .labelBox
{
stroke: #ccf;
fill: #ececff;
}
div.mermaid .labelText
{
fill: black;
stroke: none;
}
div.mermaid .loopText
{
fill: black;
stroke: none;
}
div.mermaid .loopLine
{
stroke-width: 2;
stroke-dasharray: '2 2';
marker-end: 'url(#arrowhead)';
stroke: #ccf;
}
div.mermaid .note
{
stroke: #aa3;
fill: #fff5ad;
}
div.mermaid .noteText
{
font-family: 'trebuchet ms', verdana, arial;
font-size: 14px;
fill: black;
stroke: none;
}
/** Section styling */
div.mermaid .section
{
opacity: .2;
stroke: none;
}
div.mermaid .section0
{
fill: rgba(102, 102, 255, .49);
}
div.mermaid .section2
{
fill: #fff400;
}
div.mermaid .section1,
div.mermaid .section3
{
opacity: .2;
fill: white;
}
div.mermaid .sectionTitle0
{
fill: #333;
}
div.mermaid .sectionTitle1
{
fill: #333;
}
div.mermaid .sectionTitle2
{
fill: #333;
}
div.mermaid .sectionTitle3
{
fill: #333;
}
div.mermaid .sectionTitle
{
font-size: 11px;
text-anchor: start;
text-height: 14px;
}
/* Grid and axis */
div.mermaid .grid .tick
{
opacity: .3;
stroke: lightgrey;
shape-rendering: crispEdges;
}
div.mermaid .grid path
{
stroke-width: 0;
}
/* Today line */
div.mermaid .today
{
fill: none;
stroke: red;
stroke-width: 2px;
}
/* Task styling */
/* Default task */
div.mermaid .task
{
stroke-width: 2;
}
div.mermaid .taskText
{
font-size: 11px;
text-anchor: middle;
}
div.mermaid .taskTextOutsideRight
{
font-size: 11px;
fill: black;
text-anchor: start;
}
div.mermaid .taskTextOutsideLeft
{
font-size: 11px;
fill: black;
text-anchor: end;
}
/* Specific task settings for the sections*/
div.mermaid .taskText0,
div.mermaid .taskText1,
div.mermaid .taskText2,
div.mermaid .taskText3
{
fill: white;
}
div.mermaid .task0,
div.mermaid .task1,
div.mermaid .task2,
div.mermaid .task3
{
fill: #8a90dd;
stroke: #534fbc;
}
div.mermaid .taskTextOutside0,
div.mermaid .taskTextOutside2
{
fill: black;
}
div.mermaid .taskTextOutside1,
div.mermaid .taskTextOutside3
{
fill: black;
}
/* Active task */
div.mermaid .active0,
div.mermaid .active1,
div.mermaid .active2,
div.mermaid .active3
{
fill: #bfc7ff;
stroke: #534fbc;
}
div.mermaid .activeText0,
div.mermaid .activeText1,
div.mermaid .activeText2,
div.mermaid .activeText3
{
fill: black !important;
}
/* Completed task */
div.mermaid .done0,
div.mermaid .done1,
div.mermaid .done2,
div.mermaid .done3
{
stroke: grey;
fill: lightgrey;
stroke-width: 2;
}
div.mermaid .doneText0,
div.mermaid .doneText1,
div.mermaid .doneText2,
div.mermaid .doneText3
{
fill: black !important;
}
/* Tasks on the critical line */
div.mermaid .crit0,
div.mermaid .crit1,
div.mermaid .crit2,
div.mermaid .crit3
{
stroke: #f88;
fill: red;
stroke-width: 2;
}
div.mermaid .activeCrit0,
div.mermaid .activeCrit1,
div.mermaid .activeCrit2,
div.mermaid .activeCrit3
{
stroke: #f88;
fill: #bfc7ff;
stroke-width: 2;
}
div.mermaid .doneCrit0,
div.mermaid .doneCrit1,
div.mermaid .doneCrit2,
div.mermaid .doneCrit3
{
cursor: pointer;
stroke: #f88;
fill: lightgrey;
stroke-width: 2;
shape-rendering: crispEdges;
}
div.mermaid .doneCritText0,
div.mermaid .doneCritText1,
div.mermaid .doneCritText2,
div.mermaid .doneCritText3
{
fill: black !important;
}
div.mermaid .activeCritText0,
div.mermaid .activeCritText1,
div.mermaid .activeCritText2,
div.mermaid .activeCritText3
{
fill: black !important;
}
div.mermaid .titleText
{
font-size: 18px;
text-anchor: middle;
fill: black;
}
/*
*/
div.mermaid .node text
{
font-family: 'trebuchet ms', verdana, arial;
font-size: 14px;
}
div.mermaidTooltip
{
font-family: 'trebuchet ms', verdana, arial;
font-size: 12px;
position: absolute;
z-index: 100;
max-width: 200px;
padding: 2px;
text-align: center;
pointer-events: none;
border: 1px solid #aa3;
border-radius: 2px;
background: #ffffde;
}
+54
View File
@@ -0,0 +1,54 @@
html,body,#wrapper {
width: 100%;
height: 100%;
margin: 0px;
}
.chart {
font-family: Arial, sans-serif;
font-size: 12px;
}
.axis path,.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: #33b5e5;
}
.bar-failed {
fill: #CC0000;
}
.bar-running {
fill: #669900;
}
.bar-succeeded {
fill: #33b5e5;
}
.bar-killed {
fill: #ffbb33;
}
#forkme_banner {
display: block;
position: absolute;
top: 0;
right: 10px;
z-index: 10;
padding: 10px 50px 10px 10px;
color: #fff;
background:
url('http://dk8996.github.io/Gantt-Chart/images/blacktocat.png')
#0090ff no-repeat 95% 50%;
font-weight: 700;
box-shadow: 0 0 10px rgba(0, 0, 0, .5);
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
text-decoration: none;
}
+14924
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+114244
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+25
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+21
View File
@@ -0,0 +1,21 @@
from typing import Union,List
from inn import getEngine
import markdown
from sysjobs import *
def getHtml(sysjob: List[Union[Sysjobs,Sysjobhistory]]) -> str:
resReturn: str=''
resReturn = "# Title\n"
resReturn+= "~~~mermaid\n"
resReturn+= "gantt\n"
#resReturn+= "dateFormat YYYY-MM-DD H HH\n"
for a in sysjob:
resReturn+=a[0].name + ' : ' + str(a[1].getStartTime()) + ',' + str(a[1].getRunDurationInHourMinSec())+ '\n'
resReturn+="~~~"
resReturn=markdown.markdown(resReturn, extensions=['md_mermaid'])
resReturn=resReturn.replace('<script>mermaid.initialize({startOnLoad:true});</script>','')
return resReturn
def getJson(sysjob: List[Union[Sysjobs,Sysjobhistory]]):
return ''
+141
View File
@@ -0,0 +1,141 @@
#from __future__ import annotations
from typing import List
from sqlalchemy import BOOLEAN, Column,INTEGER,NVARCHAR, ForeignKey,Select, and_, or_
from sqlalchemy.dialects.mssql import UNIQUEIDENTIFIER, TINYINT
from sqlalchemy.orm import relationship,Session,Mapped,mapped_column
from sqlalchemy.ext.declarative import declarative_base
from datetime import datetime,timedelta,time
import json
from json import JSONEncoder
#import sysjobhistory
import inn
class MyEncoder(JSONEncoder):
def default(self, obj):
if(isinstance(obj,Sysjobs) or isinstance(obj,Sysjobhistory)):
return obj.getDict()
else:
return object.__dict__
Base = declarative_base()
class Sysjobs(Base):
__tablename__ = "sysjobs"
job_id: Mapped[str] = mapped_column(UNIQUEIDENTIFIER,primary_key=True)
name=Column(NVARCHAR(128))
enabled=Column(TINYINT)
sysjobhistories: Mapped[List["Sysjobhistory"]] = relationship(back_populates="sysjob")
dataflow_jobs: Mapped[List["DataflowManagement_JobListe"]] = relationship(back_populates="sysjob")
def __iter__(self):
yield from {
"job_id": self.job_id,
"name": self.name
}.items()
def __iter__(self):
yield from {
"job_id": str(self.job_id),
"name": self.name
}.items()
def __str__(self):
return json.dumps(self.getDict())
def getDict(self):
return {'job_id': str(self.job_id), 'name': self.name}
def __repr__(self):
return self.__str__()
def getTest(self,session: Session):
stmt = Select(Sysjobs).join(Sysjobhistory).where(Sysjobhistory.run_date>20230601).distinct()
print(stmt)
with Session(engine) as session:
row : Sysjobs
res = session.execute(stmt).all()
for row in res:
print(row.Sysjobs.name + ' ' + str(row.Sysjobhistory.run_date) + ' ' + str(row.Sysjobhistory.run_time))
def getNattensKoersel(session) -> List['Sysjobs']:
natStat=(datetime.today()-timedelta(days=1)).replace(hour=20,minute=0,second=0,microsecond=0)
resReturn: List['Sysjobs'] = list()
stmt = Select(Sysjobs,Sysjobhistory).join(DataflowManagement_JobListe).join(Sysjobhistory).where(Sysjobhistory.step_id==0).where(DataflowManagement_JobListe.Aktiv==1).where(or_(and_(Sysjobhistory.run_date>=int((natStat.strftime('%Y%m%d'))),(Sysjobhistory.run_time>=int((natStat.strftime('%H%M%S'))))),Sysjobhistory.run_date>int((datetime.today().strftime('%Y%m%d'))))).distinct()
row : Sysjobs
res = session.execute(stmt).all()
# resReturn=[x[0] for x in res]
return res
class Sysjobhistory(Base):
__tablename__ = "sysjobhistory"
instance_id=Column(INTEGER,primary_key=True)
job_id: Mapped[str] = mapped_column(ForeignKey("sysjobs.job_id"))
step_id = Column(INTEGER)
step_name=Column(NVARCHAR(128))
run_date=Column(INTEGER)
run_time=Column(INTEGER)
run_duration=Column(INTEGER)
sysjob: Mapped["Sysjobs"] = relationship(back_populates="sysjobhistories")
def __iter__(self):
yield from {
"instance_id": self.instance_id,
"job_id": str(self.job_id),
"step_id": self.step_id,
"step_name": self.step_name,
"getStartTime": str(self.getStartTime()),
"getEndTime": str(self.getEndTime())
}.items()
def __str__(self):
return json.dumps(self.getDict())
def getDict(self):
return {'instance_id': self.instance_id, 'job_id': str(self.job_id), 'step_id' : self.step_id, 'step_name': self.step_name, 'getStartTime': str(self.getStartTime()), 'getEndTime': str(self.getEndTime())}
def __repr__(self):
return self.__str__()
def getTest(self):
engine=inn.getEngine("msdb")
# stmt = Select(Sysjobhistory)
# with Session(engine) as session:
# for row in session.execute(stmt).first():
# print(row)
def getStartTime(self) -> datetime:
resReturn: datetime
resReturn = datetime.fromisoformat(str(self.run_date)[0:4]+'-'+ str(self.run_date)[4:6]+'-'+str(self.run_date)[6:8]+' '+str(1000000+self.run_time)[1:3]+':'+str(1000000+self.run_time)[3:5]+':'+str(1000000+self.run_time)[5:7])
return resReturn
def getEndTime(self) -> datetime:
resReturn: datetime
resReturn = self.getStartTime()+timedelta(seconds=self.getRunDurationInSec())
return resReturn
def getRunDurationInSec(self) -> int:
resReturn: int
resReturn = 3600*(int(str(self.run_duration+1000000)[1:3]))+60*(int(str(self.run_duration+1000000)[3:5]))+(int(str(self.run_duration+1000000)[3:5]))
return resReturn
def getRunDurationInHourMinSec(self) -> str:
resReturn: str
resReturn=str(timedelta(seconds=self.getRunDurationInSec()))
return resReturn
def getRunHistory(self,Sysjob):
engine=inn.getEngine("msdb")
stmt = Select(Sysjobhistory).join(Sysjobhistory).filter(Sysjob)
with Session(engine) as session:
row : Sysjobs
res = session.execute(stmt).all()
print(res.__len__)
class DataflowManagement_JobListe(Base):
__tablename__ = "JobListe"
__table_args__ = { "schema": "dataflowmanagement.flw" }
JobID: Mapped[str] = mapped_column(ForeignKey("sysjobs.job_id"),primary_key=True)
Aktiv=Column(BOOLEAN)
sysjob: Mapped["Sysjobs"] = relationship(back_populates="dataflow_jobs")
+9
View File
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>FlaskBlog</title>
</head>
<body>
</body>
</html>
+57
View File
@@ -0,0 +1,57 @@
```mermaid
gantt
title Writing my thesis
dateFormat YYYY-MM-DD H HH
axisFormat %X
BI - Flow - DSI_CPR : 2023-06-11 20:01:58,0:08:08
BI - Flow - DSO_PAS_MDS : 2023-06-11 22:26:41,0:00:00
BI - Flow - DSO_SharedDimensions_Personale : 2023-06-11 22:21:15,0:03:03
BI - Flow - DSO_SharedDimensions_Sikkerhed : 2023-06-11 22:41:49,0:04:04
BI - Flow - DSI_IFDB_BOOKING : 2023-06-11 22:00:00,0:11:11
BI - Flow - DSI_IFDB_PAS_LPR3 : 2023-06-11 22:00:00,0:21:21
BI - Flow - DSO_SharedDimensions_Dimensions_ALLE : 2023-06-11 22:25:54,0:26:26
BI - Flow - DSI_SSI : 2023-06-11 20:01:14,0:02:02
BI - Flow - DSO_PAS_PRE : 2023-06-11 22:25:52,0:00:00
BI - Flow - DSO_SharedDimensions_SKSBrowser : 2023-06-11 22:00:39,0:03:03
BI - Flow - DSI_IFDB_MEDICIN : 2023-06-11 22:00:00,0:13:13
BI - Flow - DSO_SharedDimensions_Bridge_IFDB : 2023-06-11 22:52:16,0:10:10
BI - Flow - DSO_PAS_DIM : 2023-06-11 22:27:25,0:08:08
BI - Flow - DSO_SharedDimensions_Borger : 2023-06-11 22:21:14,0:13:13
BI - Flow - DSI_IFDB_SHARED : 2023-06-11 22:00:00,0:00:00
BI - Flow - Batch Start Daglig kl. 20.00 : 2023-06-11 20:00:00,0:02:02
BI - Flow - DSI_SST : 2023-06-11 20:01:56,0:01:01
BI - Flow - DSO_SharedDimensions_Organisation : 2023-06-11 22:21:12,0:20:20
BI - Flow - DPA_SharedDimensions : 2023-06-11 23:03:04,0:07:07
BI - Flow - DSO_SharedDimensions_Dimensions_PRE : 2023-06-11 22:21:18,0:04:04
BI - Flow - DPA_SharedDimensions_Sikkerhed : 2023-06-11 22:45:54,0:01:01
BI - Flow - DSI_IFDB_PAS_SFI : 2023-06-11 22:00:00,0:05:05
BI - Flow - DSO_PAS_FACT : 2023-06-11 23:03:00,0:47:47
BI - Flow - DSO_SharedDimensions_Shared : 2023-06-11 20:01:29,0:00:00
BI - Flow - DPA_SharedDimensions_Shared : 2023-06-11 20:01:45,0:00:00
BI - Flow - DSI_IFDB_PAS : 2023-06-11 22:00:00,0:14:14
BI - Flow - DSI_LUNAADM : 2023-06-11 20:01:13,0:03:03
```
titleTopMargin:25,
barHeight:20,
barGap:4,
topPadding:50,
leftPadding:75,
gridLineStartPadding:35,
fontSize:11,
fontFamily:'"Open-Sans", "sans-serif"',
numberSectionStyles:4,
<h1>Welcome to FlaskBlog</h1>
{{ test|safe }}
<script src="https://unpkg.com/mermaid@8.14.0/dist/mermaid.min.js">
mermaid.ganttConfig = {
titleTopMargin: 25,
barHeight: 20,
barGap: 4,
topPadding: 75,
sidePadding: 75,
};
mermaid.initialize({startOnLoad:true});
</script>
+2
View File
@@ -0,0 +1,2 @@
tmp.txt
<script src="{{ url_for('static', filename= 'mermaid.min.js') }}"></script>