Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Im trying to create a script that will read a JSON file and use the variables to select particular folders and files and save them somewhere else.

My JSON is as follows:

{
    "source_type": "folder",
    "tar_type": "gzip",
    "tar_max_age": "10",
    "source_include": {"/opt/myapp/config", "/opt/myapp/db, /opt/myapp/randomdata"}
    "target_type": "tar.gzip",
    "target_path": "/home/user/targetA"

}

So far, I have this Python Code:

import time
import os
import tarfile
import json
source_config = '/opt/myapp/config.JSON'
target_dir = '/home/user/targetA'

def main():
    with open('source_config', "r").decode('utf-8') as f:
        data = json.loads('source_config')
        for f in data["source_include", str]:
                full_dir = os.path.join(source, f)
                tar = tarfile.open(os.path.join(backup_dir, f+ '.tar.gzip'), 'w:gz')
                tar.add(full_dir)
                tar.close()

    for oldfile in os.listdir(backup_dir):
       if str(oldfile.time) < 20:
           print("int(oldfile.time)")

My traceback is:

Traceback (most recent call last):
  File "/Users/user/Documents/myapp/test/point/test/Test2.py", line 16, in <module>
    with open('/opt/myapp/config.json', "r").decode('utf-8') as f:
AttributeError: 'file' object has no attribute 'decode'

How do I fix this?

share|improve this question
 
Presumably your input JSON does not use {"/opt/myapp/config", "/opt/myapp/db, /opt/myapp/randomdata"}, but [...] instead. –  Martijn Pieters Dec 2 at 12:13
 
not sure I understand the question... –  Brendan Dec 2 at 12:33
 
Your input JSON is not valid; a list of items uses square brackets, but your input uses {...} for a list instead, and is missing a comma at the end. That line should use ["/opt/myapp/config", "/opt/myapp/db, /opt/myapp/randomdata"], to be valid. –  Martijn Pieters Dec 2 at 12:42
 
Understood! Thanks! –  Brendan Dec 2 at 12:47
add comment

1 Answer

up vote 2 down vote accepted

You are trying to call .decode() directly on the file object. You'd normally do that on the read lines instead. For JSON, however, you don't need to do this. The json library handles this for you.

Use json.load() (no s) to load directly from the file object:

with open(source_config) as f:
    data = json.load(f)

Next, you need to address the source_include key with:

for entry in data["source_include"]:
    base_filename = os.path.basename(entry)
    tar = tarfile.open(os.path.join(backup_dir, base_filename + '.tar.gzip'), 'w:gz')
    tar.add(full_dir)
    tar.close()

Your JSON also needs to be fixed, so that your source_include is an array, rather than a dictionary:

{
    "source_type": "folder",
    "tar_type": "gzip",
    "tar_max_age": "10",
    "source_include": ["/opt/myapp/config", "/opt/myapp/db", "/opt/myapp/randomdata"],
    "target_type": "tar.gzip",
    "target_path": "/home/user/targetA"

}

Next, you loop over filenames with os.listdir(), which are strings (relative filenames with no path). Strings do not have a .time attribute, if you wanted to read out file timestamps you'll have to use os.stat() calls instead:

for filename in os.listdir(backup_dir):
    path = os.path.join(backup_dir, filename)
    stats = os.stat(path)
    if stats.st_mtime < time.time() - 20:
        # file was modified less than 20 seconds ago
share|improve this answer
 
Maybe change the variable name f in the loop so it's not the same as the file object? –  Josh Smeaton Dec 2 at 12:09
 
That changes the traceback to: with open('source_config') as f: IOError: [Errno 2] No such file or directory: 'source_config' –  Brendan Dec 2 at 12:13
 
@Brendan see the with line, I removed the quotes so it uses the string in the variable source_config rather than the string "source_config" which doesn't exist as a file. –  Josh Smeaton Dec 2 at 12:15
 
@JoshSmeaton: Thanks. –  Martijn Pieters Dec 2 at 12:16
 
No problem, also added extra info regarding the json (instead of writing another answer). –  Josh Smeaton Dec 2 at 12:17
show 8 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.