1

Background: I'm using cx_Freeze to compile a larger program into an EXE. The EXE works on my machine, but will not work on any other machine.

I believe I've isolated the problem to the file creation process within the program. Below is a simplified example of what I attempt to run:

file_name = '%s\\%s.txt' % (os.getcwd(), 5)

with open(file_name, 'wb') as f:
    # do something

Again, this succesfully creates a file on my machine, however on all other machines I've tested, the following error occurs:

IOError: [Errno 22] invalid mode <'wb'> or filename: 'C:\\Users\\John G\\5.txt'

Initially I thought the double slashes (\) in the filepath were the root cause, but I no longer believe they are the issue because when I print file_name on the other machine, the output is normal: C:\Users\John G\5.txt

Can someone explain why this code runs successfully on my machine but fails on other machines? All machines are running Windows 10. One had Python installed and the other did not -- both failed.

EDIT: full code included below. The IO error occurs at with open(name_text) as f:

def main(file_path):
    with open(file_path, 'rb') as pdf_file:
        pdf_buffer = StringIO(pdf_file.read())

    try:
        input_pdf = pyPdf.PdfFileReader(pdf_buffer)
    except:
        input_pdf = pyPdf.PdfFileReader(decompress_pdf(pdf_buffer))

    no_of_pages = input_pdf.getNumPages()

    headers = []
    row_list = []
    text = []
    count = 0

    for i in range(no_of_pages):
        writer = pyPdf.PdfFileWriter()
        page = input_pdf.getPage(i)
        writer.addPage(page)
        file_name = '%s\\%s.pdf' % (os.getcwd(), count)
        newFile = open(file_name,'wb')
        writer.write(newFile)
        newFile.close()
        count += 1

        try:
            process = subprocess.call(['pdftotext', '-layout', file_name])
        except:
            print 'fail'

        name_text = re.sub('.pdf$','.txt',file_name)
        with open(name_text) as f:
            for line in f:
                line = line.decode('ascii','ignore').replace('\n','').replace(',','').replace(';','').strip()
                if line != '':
                    text.append(line)
        os.remove(name_text)
        os.remove(file_name)


        details_start = ''
        details_end = ''
        details_dict = {}

        attribute_start = ''

        details_bool = True
        attributes_bool = False

        for x,y in enumerate(text):
            if 'DATABASE' in y:
                details_start = int(x +1)
            if 'PostingBody' in y:
                details_end = int(x)
                #print details_end
            if 'Attributes' in y:
                attribute_start = int(x)
                attributes_bool = True

        renewal_dates = []

        for x in range(details_start, details_end):
            if 'posting_renewal_dates' in text[x]:
                n = 0
                #print text[x].split(':')[1].strip()
                if text[x].split(':')[1].strip() != 'n/a':
                    testbool = True
                    while testbool:
                        if not 'record_modified:' in text[x+n]:
                            if 'posting_renewal_dates:' in text[x+n]:
                                renewal_dates.append( text[x+n].split(': ')[1] )
                            else:
                                renewal_dates.append( text[x+n] )
                            n += 1
                        else:
                            testbool = False
            elif not text[x][0].isupper():
                #print text[x]
                key = text[x].split(':')[0]
                value = text[x].split(':')[1]



            if key != '':
                details_dict[key] = value

        try:
            xObject = page['/Resources']['/XObject'].getObject()
            for obj in xObject:
                if xObject[obj]['/Subtype'] == '/Image':
                    size = (xObject[obj]['/Width'], xObject[obj]['/Height'])
                    data = xObject[obj].getData()

                    mode = "RGB"
                    try:
                        if not os.path.exists('%s/%s' % (new_folder, details_dict['posting_id'])):
                            os.mkdir('%s/%s' % (new_folder, details_dict['posting_id'].strip(' ')))
                            img_dir = '%s/%s' % (new_folder, details_dict['posting_id'].strip(' '))
                            print 'Success -- ' + img_dir
                        else:
                            print "Directory already exists"
                    except:
                        print 'Directory %s already exists' % details_dict['posting_id']
                    #print xObject[obj]['/Filter']
                    #print xObject[obj]['/ColorSpace']
                    if xObject[obj]['/Filter'] == '/FlateDecode':
                        img = Image.frombytes(mode, size, data)
                        img.save(img_dir + '\\' + obj[1:] + ".jpg")
                    elif xObject[obj]['/Filter'] == '/DCTDecode':
                        img = open(obj[1:] + ".jpg", "wb")
                        img.write(data)
                        img.close()
                    elif xObject[obj]['/Filter'] == '/JPXDecode':
                        img = open(obj[1:] + ".jp2", "wb")
                        img.write(data)
                        img.close()
        except:
            print 'No images found for %s' % details_dict['posting_id']


        body = ''
        if attributes_bool:
            for x in range(details_end+2, attribute_start):
                body += text[x] + ' '
        else:
            for x in range(details_end+2, len(text)-1):
                body += text[x] + ' '

        attributes_dict = {}
        if attributes_bool:
            for x in range(attribute_start+2, len(text)-1):
                try:
                    key = text[x].split(':')[0]
                    value = text[x].split(':')[1]
                except:
                    pass

            attributes_dict[key] = value

        row = []

        for x in details_dict:
            if not x in headers:
                headers.append(x)
            row.append(details_dict[x])

        if not 'body' in headers:
            headers.append('body')
        row.append(body)

        row_list.append(row)

    with open(filename, 'wb') as f:
        csvwriter = csv.writer(f)
        csvwriter.writerow(headers)
        for x in row_list:
            csvwriter.writerow(x)
Jon Behnken
  • 560
  • 1
  • 3
  • 14
  • 2
    Maybe you have no write access on other machines to that folder. – Attila Bognár Dec 12 '18 at 15:01
  • 1
    I am not sure this changes anything, but a better way to join file paths would be `os.path.join(os.getcwd(), '%s.txt' % 5)`. – glglgl Dec 12 '18 at 15:08
  • @AttilaBognár Write access doesn't seem to be the problem. I normally have write access to all relevant folders and I've run as administrator just to be sure and the same error persists. – Jon Behnken Dec 12 '18 at 15:13
  • @AttilaBognár Possible, but unlikely, as this is probably the user home folder on the respective machine. Unlikely that this is not writable by the user. – glglgl Dec 12 '18 at 15:14
  • @glglgl I tried your file path method and the same error occurs. – Jon Behnken Dec 12 '18 at 15:17
  • Windows may think an .EXE from an untrusted source (e.g. network share) and may block writing. Check the properties of the .EXE and see if the block can be removed. – Mark Tolonen Dec 12 '18 at 16:52
  • @MarkTolonen wouldn't that result in a different error, like [IOError Errno 13](https://stackoverflow.com/questions/29331872/ioerror-errno-13-permission-denied)? – Jon Behnken Dec 12 '18 at 17:08
  • Just a suggestion. Both parameters look fine. Does it run as a script on other machines without cx_Freeze? – Mark Tolonen Dec 12 '18 at 17:20
  • have you tried to just create `5.txt` ? as `os.getcwd()` isn't useful. Python can open fles in relative path. That would make your question clearer & simpler – Jean-François Fabre Dec 12 '18 at 19:55
  • also can you post the python version you're using? – Jean-François Fabre Dec 12 '18 at 19:58
  • @Jean-FrançoisFabre I'm using Python 2.7. The script normally does not use `os.getcwd()` -- I initially included it in this test script to determine whether it was an error with filepath slashes. Simply creating `5.txt` results in the same error. I'm going to attempt to run as a script on one machine and I will post the results. – Jon Behnken Dec 12 '18 at 20:02
  • it would help if you posted your exact code. Because it very much looks like a duplicate of https://stackoverflow.com/questions/15141761/region-ioerror-errno-22-invalid-mode-w-or-filename – Jean-François Fabre Dec 12 '18 at 20:05
  • @Jean-FrançoisFabre I included the full code. It's not a backslash issue as I've used `os.path.join()` and the same error occurs. I'm beginning to think it's a cx_Freeze error, although the EXE runs fine on my machine. I'm going to test the script itself on one of the external machines and post the results. – Jon Behnken Dec 12 '18 at 20:33

0 Answers0