Skip to content

File

src.drawpyo.file.File

Bases: XMLBase

The File class defines a Draw.io file, its properties, and the methods required for saving it.

Source code in src/drawpyo/file.py
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
class File(XMLBase):
    """The File class defines a Draw.io file, its properties, and the methods required for saving it."""

    def __init__(
        self,
        file_name="Drawpyo Diagram.drawio",
        file_path=path.join(path.expanduser("~"), "Drawpyo Charts"),
    ):
        """To initiate a File object, pass in a name and path or leave it to the defaults.

        Args:
            file_name (str, optional): The name of the file.
            file_path (str, optional): The location where the file will be saved.
        """

        super().__init__()

        self.pages = []
        self.file_name = file_name
        self.file_path = file_path

        # Attributes
        self.host = "Drawpyo"
        self.type = "device"
        self.version = "21.6.5"  # This is the version of the Draw.io spec
        self.xml_class = "mxfile"

    def __repr__(self):
        return f"drawpyo File - {self.file_name}"

    @property
    def attributes(self):
        return {
            "host": self.host,
            "modified": self.modified,
            "agent": self.agent,
            "etag": self.etag,
            "version": self.version,
            "type": self.type,
        }

    def add_page(self, page):
        """Add a page to the file.

        Args:
            page (drawpyo.diagram.Page): A Page object
        """
        page._file = self
        self.pages.append(page)

    def remove_page(self, page):
        """Remove a page from the file. The page argument can be either a Page object, the integer number of the page, or the string name of the page.

        Args:
            page (drawpyo.diagram.Page or str or int): A Page object that's currently contained in the file
        """
        if isinstance(page, int):
            del self.pages[page]
        elif isinstance(page, str):
            for pg in self.pages:
                if pg.name == page:
                    self.pages.remove(pg)
        elif isinstance(page, Page):
            self.pages.remove(page)

    ###########################################################
    # File Properties
    ###########################################################

    @property
    def modified(self):
        return datetime.now().strftime("%Y-%m-%dT%H:%M:%S")

    @property
    def agent(self):
        python_version = f"{version_info.major}.{version_info.minor}"
        drawpyo_version = f"0.01"
        return f"Python {python_version}, Drawpyo {drawpyo_version}"

    @property
    def etag(self):
        # etag is in the Draw.io spec but not sure how it's used or if I need to create it
        return None

    ###########################################################
    # XML Generation
    ###########################################################

    @property
    def xml(self):
        """This function goes through each page in the file, retrieves its XML, and appends it to a list, then wraps that list in the file's open and close tags.

        Returns:
            str: The XML data for the file and all the pages in it
        """
        xml_string = self.xml_open_tag
        for diag in self.pages:
            xml_string = xml_string + "\n  " + diag.xml
        xml_string = xml_string + "\n" + self.xml_close_tag
        return xml_string

    ###########################################################
    # File Handling
    ###########################################################
    def write(self, **kwargs):
        """This function write the file to disc at the path and name specified.

        Args:
            file_path (str, opt): The path to save the file in
            file_name (str, opt): The name of the file
            overwrite (bool, opt): Whether to overwrite an existing file or not
        """

        # Check if file_path or file_name were passed in, or are preexisting
        self.file_path = kwargs.get("file_path", self.file_path)

        self.file_name = kwargs.get("file_name", self.file_name)

        overwrite = kwargs.get("overwrite", True)
        if overwrite:
            write_mode = "w"
        else:
            write_mode = "x"

        if not path.exists(self.file_path):
            makedirs(self.file_path)

        with open(
            path.join(self.file_path, self.file_name), write_mode, encoding="utf-8"
        ) as f:
            f.write(self.xml)

        return path.join(self.file_path, self.file_name)

xml property

This function goes through each page in the file, retrieves its XML, and appends it to a list, then wraps that list in the file's open and close tags.

Returns:

Name Type Description
str

The XML data for the file and all the pages in it

__init__(file_name='Drawpyo Diagram.drawio', file_path=path.join(path.expanduser('~'), 'Drawpyo Charts'))

To initiate a File object, pass in a name and path or leave it to the defaults.

Parameters:

Name Type Description Default
file_name str

The name of the file.

'Drawpyo Diagram.drawio'
file_path str

The location where the file will be saved.

join(expanduser('~'), 'Drawpyo Charts')
Source code in src/drawpyo/file.py
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
def __init__(
    self,
    file_name="Drawpyo Diagram.drawio",
    file_path=path.join(path.expanduser("~"), "Drawpyo Charts"),
):
    """To initiate a File object, pass in a name and path or leave it to the defaults.

    Args:
        file_name (str, optional): The name of the file.
        file_path (str, optional): The location where the file will be saved.
    """

    super().__init__()

    self.pages = []
    self.file_name = file_name
    self.file_path = file_path

    # Attributes
    self.host = "Drawpyo"
    self.type = "device"
    self.version = "21.6.5"  # This is the version of the Draw.io spec
    self.xml_class = "mxfile"

add_page(page)

Add a page to the file.

Parameters:

Name Type Description Default
page Page

A Page object

required
Source code in src/drawpyo/file.py
49
50
51
52
53
54
55
56
def add_page(self, page):
    """Add a page to the file.

    Args:
        page (drawpyo.diagram.Page): A Page object
    """
    page._file = self
    self.pages.append(page)

remove_page(page)

Remove a page from the file. The page argument can be either a Page object, the integer number of the page, or the string name of the page.

Parameters:

Name Type Description Default
page Page or str or int

A Page object that's currently contained in the file

required
Source code in src/drawpyo/file.py
58
59
60
61
62
63
64
65
66
67
68
69
70
71
def remove_page(self, page):
    """Remove a page from the file. The page argument can be either a Page object, the integer number of the page, or the string name of the page.

    Args:
        page (drawpyo.diagram.Page or str or int): A Page object that's currently contained in the file
    """
    if isinstance(page, int):
        del self.pages[page]
    elif isinstance(page, str):
        for pg in self.pages:
            if pg.name == page:
                self.pages.remove(pg)
    elif isinstance(page, Page):
        self.pages.remove(page)

write(**kwargs)

This function write the file to disc at the path and name specified.

Parameters:

Name Type Description Default
file_path (str, opt)

The path to save the file in

required
file_name (str, opt)

The name of the file

required
overwrite (bool, opt)

Whether to overwrite an existing file or not

required
Source code in src/drawpyo/file.py
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
def write(self, **kwargs):
    """This function write the file to disc at the path and name specified.

    Args:
        file_path (str, opt): The path to save the file in
        file_name (str, opt): The name of the file
        overwrite (bool, opt): Whether to overwrite an existing file or not
    """

    # Check if file_path or file_name were passed in, or are preexisting
    self.file_path = kwargs.get("file_path", self.file_path)

    self.file_name = kwargs.get("file_name", self.file_name)

    overwrite = kwargs.get("overwrite", True)
    if overwrite:
        write_mode = "w"
    else:
        write_mode = "x"

    if not path.exists(self.file_path):
        makedirs(self.file_path)

    with open(
        path.join(self.file_path, self.file_name), write_mode, encoding="utf-8"
    ) as f:
        f.write(self.xml)

    return path.join(self.file_path, self.file_name)