site_graphlogo
  -   Terms of Use and Privacy
Source Code
site_graphlogo
  -   Terms of Use and Privacy
Source Code

Source Code | system COMPonent GRa(F) generation

This program creates the component graphs. It is also an example of how to create custom Graphviz nodes.

#!/usr/bin/python3
#system COMPonent GRa(F) generation
#Copyright (C) 2020 Tributary Software

#This program is free software; you can redistribute it and/or
#modify it under the terms of the GNU General Public License
#as published by the Free Software Foundation; either version 2
#of the License, or (at your option) any later version.

#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.

#You should have received a copy of the GNU General Public License
#along with this program; if not, write to the Free Software
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
#or view the license here: https://tributarysoftware.com/gpl2.txt
import re
import os
import sys
import time
import codecs
import pprint
import collections
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
diaghead='digraph {\ncharset=\"utf-8\";'
diaghead+='overlap=\"false\";\n'
diaghead+='splines=\"true\";\n'
diaghead+='sep=\"+10\";\n'
hd=''
out='/home/knoppix/websites/site/'+sys.argv[1]+'/graph/'
rootdfd='/home/knoppix/websites/source/'+sys.argv[1]+'/'
ps='/home/knoppix/websites/postscript/'
version=''
def rendergv(path):
   fil=path.replace('/','.')
   os.system('sfdp -Tps -l '+ps+'network.ps '+out+fil+'.gv -o '+out+fil+'.ps')
   os.system('ps2eps -B -C < '+out+fil+'.ps > '+out+fil+'.eps')
   os.system('inkscape '+out+fil+'.eps -l '+out+fil+'.svg')
   fff = codecs.open(out+fil+'.svg', mode='r', encoding='utf-8')
   rawsvg=fff.read().replace('<?xml version="1.0" encoding="UTF-8" standalone="no"?>','<div id="container" style="width: 100%; height: 95vh;">')
   rawsvg=rawsvg.replace('fill:#012312','fill:currentColor')
   rawsvg=rawsvg.replace('stroke:#012312','stroke:currentColor')
   rawsvg=rawsvg.replace('stroke:none','stroke:currentColor')
   rawsvg=rawsvg.replace('xmlns:dc="http://purl.org/dc/elements/1.1/"\n','')
   rawsvg=rawsvg.replace('xmlns:cc="http://creativecommons.org/ns#"\n','')
   rawsvg=rawsvg.replace('xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"\n','')
   rawsvg=rawsvg.replace('xmlns:svg="http://www.w3.org/2000/svg"\n','')
   rawsvg=rawsvg.replace('xmlns:xlink="http://www.w3.org/1999/xlink"\n','')
   rawsvg=rawsvg.replace('<svg\n','<svg id="Graph"\n')
   rawsvg=rawsvg.replace('stroke:#000000','stroke:currentColor')
   rawsvg=rawsvg.replace('font-size="14.00"\n','')
   rawsvg=rawsvg.replace('font-family="Times,serif"\n','')
   rawsvg=re.sub('id="svg.+"','',rawsvg)
   rawsvg=re.sub('height=".+"','',rawsvg)
   rawsvg=re.sub('width=".+"','',rawsvg)
   rawsvg=re.sub('<metadata.+</metadata>','',rawsvg,flags=re.DOTALL)
   fff.close
   rawsvg2=rawsvg.replace('<div id="container" style="width: 100%; height: 95vh;">','')
   fff = codecs.open(out+fil+'.e.svg', mode='w', encoding='utf-8')
   fff.write(rawsvg2)
   fff.close
   header=""
   try:
      numlev=level[level.rfind('/')+1:]
      numrest=level[:level.rfind('/')]
      headingraw=rootdfd+numrest+'/'+numlev+'.title.txt'
      with open(headingraw,'r') as hdraw:
         headr=hdraw.read()
      heading=headr.replace('\n',' ')
   except:
      header=''
      with open(rootdfd+'title.txt','r') as hdraw:
         headr=hdraw.read()
      heading=headr.replace('\n',' ')
   f = codecs.open(out+fil+'.txt', mode='w', encoding='utf-8')
   tp='<div class="rhead"><div class="parent"><div class="level">'+header+'</div><div class="heading">'+heading+'</div></div></div>'
   tp+='<div class="rhead-push"><div class="parent"><div class="level">'+header+'</div><div class="heading">'+heading+'</div></div></div>'
   f.write(tp+rawsvg)
   f.close
def createflow(path):
   labels={}
   global hd
   graph=[]
   for root,dirs,files in os.walk(rootdfd+path+'/', followlinks=False):
      for fname in files:
         if not fname.startswith('.') and fname[-11:]!='details.txt':
            p=os.path.join(root,fname)
            bits=re.compile(re.escape(rootdfd+path+'/')+r'(.+)/(has_component_destination)/(.+)')
            try:
               m = bits.match(p)
               subject=m.group(1)
               predicate=m.group(2)
               objctraw=m.group(3)
               ttl=objctraw.find('title.txt')
               if ttl==-1:
                  objct=objctraw[:-4]
                  objctp=objctraw
               else:
                  objct=objctraw[:ttl-1]
                  objctp=objctraw
               lbl=''
               lblline=''
               if os.path.isfile(rootdfd+path+'/'+subject+'/'+predicate+'/'+objct+'.details.txt') and fname.find('^^')==-1 and fname.find('_has_specified')==-1 and fname.find('_flow_destination')==-1:
                  with open(rootdfd+path+'/'+subject+'/'+predicate+'/'+objct+'.details.txt','r') as linelbl:
                     lblline=linelbl.read().replace('\n',' ')
               else:
                  lblline=''
               graph.append('"'+subject+'" -> "'+objct+'" [dir="none" color="#012312" label="'+lblline+'"];')
               lbls=''
               with open(rootdfd+path+'/'+subject+'.txt','r') as label:
                  for line in label:
                     lbls+=line.rstrip()+r'\n'
               with open(rootdfd+path+'/'+objct+'.txt','r') as label:
                  for line in label:
                     lbl+=line.rstrip()+r'\n'
               if subject[0]=='N':
                  labels[subject]='"'+subject+'" [shape="network" peripheries="0" fontcolor="#012312" label="'+lbls+'" ];'
               if objct[0]=='N':
                  labels[objct]='"'+objct+'" [shape="network" peripheries="0" fontcolor="#012312" label="'+lbl+'" ];'
               if subject[0]=='R':
                  labels[subject]='"'+subject+'" [shape="square" style="diagonals" fontcolor="#012312" label="'+lbls+'" ];'
               if objct[0]=='R':
                  labels[objct]='"'+objct+'" [shape="square" style="diagonals" fontcolor="#012312" label="'+lbl+'" ];'
               if subject[0]=='S':
                  labels[subject]='"'+subject+'" [shape="box", style=rounded fontcolor="#012312" label="'+lbls+'" ];'
               if objct[0]=='S':
                  labels[objct]='"'+objct+'" [shape="box", style=rounded fontcolor="#012312" label="'+lbl+'" ];'
               if subject[0]=='D':
                  labels[subject]='"'+subject+'" [shape="cylinder" fontcolor="#012312" label="'+lbls+'" ];'
               if objct[0]=='D':
                  labels[objct]='"'+objct+'" [shape="cylinder" fontcolor="#012312" label="'+lbl+'" ];'
               lbl=''
               with open(rootdfd+path+'/'+subject+'.title.txt','r') as label:
                  for line in label:
                     lbl+=line.rstrip()+r'\n'
               try:
                  with open(rootdfd+path+'/'+subject+'.details.txt','r') as linelbl:
                     lblline=linelbl.read().replace('\n',' ')
                     lbllinel='*'
               except:
                  lblline=''
                  lbllinel=''
               end=('tooltip="'+lblline+'"];')
               labels[subject]='"'+subject+'" [fontcolor="#012312" label="{<f0> '+lbllinel+' '+subject+'|<f1> '+lbl+'\n\n\n}" shape=Mrecord '+end
            except:
               six=9
   alll=''
   for line in labels:
      alll+=labels[line]+'\n'
   for line in graph:
      alll+=line+'\n'
   with open(out+path.replace('/','.')+'.gv', 'w+') as fa:
      fa.write(diaghead+alll+'}'+'\n')
   rendergv(path)
def update(evt):
   print(evt)
   proc=''
   hass=evt.find('/has_component_destination')
   if hass !=-1:
      subject=evt[:hass].rfind('/')
      createflow(evt[len(rootdfd):subject])
class changes(FileSystemEventHandler):
   def on_modified(self, event):
      update(event.src_path)
   def on_created(self, event):
      update(event.src_path)
if __name__ == "__main__":
   event_handler = changes()
   observer = Observer()
   observer.schedule(event_handler, rootdfd, recursive=True)
   observer.start()
   try:
      while True:
         time.sleep(1)
   except KeyboardInterrupt:
      observer.stop()
      observer.join()

raw source