1# -*- coding: utf-8 -*-2# Copyright 2011 Takeshi KOMIYA3#4# Licensed under the Apache License, Version 2.0 (the "License");5# you may not use this file except in compliance with the License.6# You may obtain a copy of the License at7#8# http://www.apache.org/licenses/LICENSE-2.09#10# Unless required by applicable law or agreed to in writing, software11# distributed under the License is distributed on an "AS IS" BASIS,12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13# See the License for the specific language governing permissions and14# limitations under the License.1516import re1718import blockdiag.elements19from blockdiag.utils import images, unquote202122class NodeGroup(blockdiag.elements.NodeGroup):23 pass242526class DiagramNode(blockdiag.elements.DiagramNode):27 def __init__(self, _id):28 super(DiagramNode, self).__init__(_id)2930 self.address = {}31 self.networks = []32 self.layouted = False3334 def set_attributes(self, network, attrs=None):35 if attrs is None:36 attrs, network = network, None3738 for attr in attrs:39 if attr.name == 'address':40 address = re.sub(r'\s*,\s*', '\n', unquote(attr.value))41 self.address[network] = address42 else:43 self.set_attribute(attr)444546class DiagramEdge(blockdiag.elements.DiagramEdge):47 pass484950class Network(blockdiag.elements.NodeGroup):51 basecolor = (185, 203, 228)52 linecolor = (0, 0, 0)535455 def set_default_linecolor(cls, color):56 cls.linecolor = images.color_to_rgb(color)575859 def set_default_textcolor(cls, color):60 cls.textcolor = images.color_to_rgb(color)616263 def clear(cls):64 super(Network, cls).clear()65 cls.basecolor = (185, 203, 228)66 cls.linecolor = (0, 0, 0)6768 def __init__(self, _id):69 super(Network, self).__init__(_id)7071 self.address = None72 self.hidden = False73 self.colwidth = 174 self.colheight = 1757677 def create_anonymous(cls, nodes, attrs=None):78 def is_same(nw):79 return set(nodes) & set(nw.nodes) == set(nodes)8081 if len(set(nodes)) != len(nodes):82 msg = "Do not connect same node to peer network: %s"83 raise RuntimeError(msg % nodes[0].id)8485 # search networks including same nodes86 if [nw for nw in nodes[0].networks if nw.hidden and is_same(nw)]:87 return None8889 network = cls(None)90 network.hidden = True91 for node in nodes:92 node.networks.append(network)93 network.nodes.append(node)9495 if attrs:96 node.set_attributes(network, attrs)9798 return network99100101 def display_label(self):102 if self.label:103 if self.address:104 label = "%s\n%s" % (self.label, self.address)105 else:106 label = self.label107 else:108 label = self.address109110 return label111112113class Route(blockdiag.elements.DiagramEdge):114 pass115116117class Diagram(blockdiag.elements.Diagram):118 _DiagramNode = DiagramNode119 _Network = Network120 _Route = Route121122 def set_default_linecolor(self, color):123 super(Diagram, self).set_default_linecolor(color)124 self._Network.set_default_linecolor(self.linecolor)125126 def set_default_textcolor(self, color):127 super(Diagram, self).set_default_textcolor(color)128 self._Network.set_default_text_color(self.textcolor)129130 def set_default_fontsize(self, fontsize):131 super(Diagram, self).set_default_fontsize(fontsize)132 self._Network.set_default_fontsize(fontsize)133134 def set_default_fontfamily(self, familyname):135 super(Diagram, self).set_default_fontfamily(familyname)136 self._Network.set_default_fontfamily(familyname)137138 def set_default_network_color(self, color):139 color = images.color_to_rgb(color)140 self._Network.set_default_color(color)141142 def __init__(self):143 super(Diagram, self).__init__()144145 self.orientation = 'portrait'146 self.external_connector = True147 self.groups = []148 self.networks = []149 self.routes = []150151 def set_external_connector(self, value):152 value = value.lower()153 if value == 'none':154 self.external_connector = False155 else:156 msg = "unknown external connector: %s\n" % value157 raise AttributeError(msg)158159 def fixiate(self):160 self.colwidth = max(n.xy.x + n.colwidth for n in self.nodes)161 self.colheight = max(n.xy.y + n.colheight for n in self.nodes)162163 colheight = max(nw.xy.y + nw.colheight - 1 for nw in self.networks)164 if self.colheight < colheight:165 self.colheight = colheight