aboutsummaryrefslogtreecommitdiff
blob: 478570da90aff958fe7381c79d93873a3e31dbdc (plain)
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
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
    fileutils.py
    ~~~~~~~~~~~~
    
    file utilities
    
    :copyright: (c) 2013 by Jauhien Piatlicki
    :license: GPL-2, see LICENSE for more details.
"""

import json, os, shutil

from .exceptions import FileJSONError
from .g_collections import Package, elist

class FileJSON(object):
    """
    Class for JSON files.
    """
    def __init__(self, directory, name, mandatories, loadconv=None):
        """
        Args:
            directory: File directory.
            name: File name.
            mandatories: List of requiered keys.
            loadconv: Type change values on loading.
        """
        self.directory = os.path.abspath(directory)
        self.name = name
        self.path = os.path.join(directory, name)
        self.mandatories = mandatories
        self.loadconv = loadconv

    def read(self):
        """
        Read JSON file.
        """
        if not os.path.exists(self.directory):
            os.makedirs(self.directory)
        content = {}
        if not os.path.isfile(self.path):
            for key in self.mandatories:
                content[key] = ""
            with open(self.path, 'w') as f:
                json.dump(content, f, indent=2, sort_keys=True)
        else:
            with open(self.path, 'r') as f:
                content = json.load(f)
            for key in self.mandatories:
                if not key in content:
                    raise FileJSONError('lack of mandatory key: ' + key)
                
        if self.loadconv:
            for key, conv in self.loadconv.items():
                if key in content:
                    content[key] = conv(content[key])
        
        return content

    def write(self, content):
        """
        Write JSON file.
        """
        for key in self.mandatories:
            if not key in content:
                raise FileJSONError('lack of mandatory key: ' + key)
        if not os.path.exists(self.directory):
            os.makedirs(self.directory)
        with open(self.path, 'w') as f:
            json.dump(content, f, indent=2, sort_keys=True)

            
def package_conv(lst):
    return Package(lst[0], lst[1], lst[2])

def dependencies_conv(dependencies):
    result = []
    for dependency in dependencies:
        result.append(package_conv(dependency))
    return result

def depend_conv(depend):
    return elist(depend, separator='\n\t')
            
class FilePkgDesc(FileJSON):
    def __init__(self, directory, name, mandatories):
        loadconv = {'dependencies' : dependencies_conv,
                    'depend' : depend_conv,
                    'rdepend' : depend_conv}
        super(FilePkgDesc, self).__init__(directory, name, mandatories, loadconv)


def hash_file(name, hasher, blocksize=65536):
    """
    Get a file hash.

    Args:
        name: file name.
        hasher: Hasher.
        blocksize: Blocksize.

    Returns:
        Hash value.
    """
    with open(name, 'rb') as f:
        buf = f.read(blocksize)
        while len(buf) > 0:
            hasher.update(buf)
            buf = f.read(blocksize)
    return hasher.hexdigest()

def copy_all(src, dst):
    """
    Copy entire tree.

    Args:
       src: Source.
       dst: Destination.
    """
    for f_name in os.listdir(src):
        src_name = os.path.join(src, f_name)
        dst_name = os.path.join(dst, f_name)
        if os.path.isdir(src_name):
            shutil.copytree(src_name, dst_name)
        else:
            shutil.copy2(src_name, dst_name)

def wget(uri, directory):
    """
    Fetch a file.

    Args:
        uri: URI.
        directory: Directory where file should be saved.

    Returns:
        Nonzero in case of a failure.
    """
    return os.system('wget -P ' + directory + ' ' + uri)

def get_pkgpath(root = None):
    """
    Get package path.

    Returns:
        Package path.
    """
    if not root:
        root = __file__
    if os.path.islink(root):
        root = os.path.realpath(root)
    return os.path.dirname(os.path.abspath(root))