This file is indexed.

/usr/lib/python2.7/dist-packages/stetl/outputs/execoutput.py is in python-stetl 1.1+ds-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# -*- coding: utf-8 -*-
#
# Output classes for ETL, executing commands.
#
# Author: Frank Steggink
#
import subprocess
import os
import shutil
from stetl.component import Config
from stetl.output import Output
from stetl.util import Util
from stetl.packet import FORMAT

log = Util.get_log('execoutput')


class ExecOutput(Output):
    """
    Executes any command (abstract base class).
    """

    def __init__(self, configdict, section, consumes):
        Output.__init__(self, configdict, section, consumes)

    def write(self, packet):
        return packet

    def execute_cmd(self, cmd):
        use_shell = True
        if os.name == 'nt':
            use_shell = False

        log.info("executing cmd=%s" % cmd)
        subprocess.call(cmd, shell=use_shell)
        log.info("execute done")


class CommandExecOutput(ExecOutput):
    """
    Executes an arbitrary command.

    consumes=FORMAT.string
    """

    def __init__(self, configdict, section):
        ExecOutput.__init__(self, configdict, section, consumes=FORMAT.string)

    def write(self, packet):
        if packet.data is not None:
            self.execute_cmd(packet.data)

        return packet


class Ogr2OgrExecOutput(ExecOutput):
    """
    Executes an Ogr2Ogr command.
    Input is a file name to be processed.
    Output by calling Ogr2Ogr command.

    consumes=FORMAT.string
    """

    # Start attribute config meta
    # Applying Decorator pattern with the Config class to provide
    # read-only config values from the configured properties.

    @Config(ptype=str, default=None, required=True)
    def dest_data_source(self):
        """
        String denoting the OGR data destination. Usually a path to a file like "path/rivers.shp" or connection string
        to PostgreSQL like "PG: host=localhost dbname='rivers' user='postgres'".
        """
        pass

    @Config(ptype=str, default=None, required=False)
    def dest_format(self):
        """
        Instructs GDAL to use driver by that name to open data destination. Not required for
        many standard formats that are self-describing like ESRI Shapefile.

        Examples: 'PostgreSQL', 'GeoJSON' etc
        """
        pass

    @Config(ptype=str, default=None, required=False)
    def lco(self):
        """
        Options for newly created layer (-lco).
        """

        pass

    @Config(ptype=str, default=None, required=False)
    def spatial_extent(self):
        """
        Spatial extent (-spat), to pass as xmin ymin xmax ymax
        """
        pass

    @Config(ptype=str, default=None, required=False)
    def gfs_template(self):
        """
        Name of GFS template file to use during loading. Passed to ogr2ogr as
        --config GML_GFS_TEMPLATE <name>
        """
        pass

    @Config(ptype=str, default=None, required=False)
    def options(self):
        """
        Miscellaneous options to pass to ogr2ogr.
        """
        pass

    @Config(ptype=bool, default=False, required=False)
    def cleanup_input(self):
        """
        Flag to indicate whether the input file to ogr2ogr should be cleaned up.
        """

        pass

    # End attribute config meta

    def __init__(self, configdict, section):
        ExecOutput.__init__(self, configdict, section, consumes=FORMAT.string)

        self.ogr2ogr_cmd = 'ogr2ogr -f ' + self.dest_format + ' ' + self.dest_data_source

        if self.spatial_extent:
            self.ogr2ogr_cmd += ' -spat ' + self.spatial_extent
        if self.options:
            self.ogr2ogr_cmd += ' ' + self.options

        self.first_run = True

    def write(self, packet):
        if packet.data is None:
            return packet

        # Execute ogr2ogr
        ogr2ogr_cmd = self.ogr2ogr_cmd
        if self.lco and self.first_run is True:
            ogr2ogr_cmd += ' ' + self.lco
            self.first_run = False

        if type(packet.data) is list:
            for item in packet.data:
                self.execute(ogr2ogr_cmd, item)
        else:
            self.execute(ogr2ogr_cmd, packet.data)

        return packet

    def execute(self, ogr2ogr_cmd, file_path):

        # For creating tables the GFS file needs to be newer than
        # the .gml file. -lco GML_GFS_TEMPLATE somehow does not work
        # so we copy the .gfs file each time with the .gml file with
        # the same base name
        # Copy the .gfs file if required, use the same base name
        # so ogr2ogr will pick it up.
        gfs_path = None
        if self.gfs_template:
            file_ext = os.path.splitext(file_path)
            gfs_path = file_ext[0] + '.gfs'
            shutil.copy(self.gfs_template, gfs_path)

        # Append file name to command as last argument
        self.execute_cmd(ogr2ogr_cmd + ' ' + file_path)

        if self.cleanup_input:
            os.remove(file_path)
            if gfs_path:
                os.remove(gfs_path)