aboutsummaryrefslogtreecommitdiff
path: root/license_protected_downloads/render_text_files.py
blob: de5f5b053137b8ddaea465f4d7a6599c422a0d3d (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
156
157
158
159
import os
import textile
import OrderedDict
from django.conf import settings


HOWTO_PATH = "howto"
HOWTO_PRODUCT_PATH = "target/product"


class MultipleFilesException(Exception):
    pass


class RenderTextFiles:

    def __init__(self):
        pass

    @classmethod
    def sort_tabs_by_priority(cls, a, b):
        base_list = settings.TAB_PRIORITY
        return base_list.index(a[0]) - base_list.index(b[0])

    @classmethod
    def find_and_render(cls, path):

        result = {}

        try:
            filepaths = cls.find_relevant_files(path)
        except:
            # This is ok, no tabs when multiple returned.
            return None

        if filepaths:
            for filepath in filepaths:
                title = settings.FILES_MAP[os.path.basename(filepath)]
                result[title] = cls.render_file(filepath)

        if not filepaths and len(result) == 0:
            return None

        result_items = sorted(result.items(), cmp=cls.sort_tabs_by_priority)
        result = OrderedDict.OrderedDict()
        for v, k in result_items:
            result[v] = k
        return result

    @classmethod
    def render_file(cls, filepath):
        try:
            file_obj = open(filepath, 'r')
            return textile.textile(file_obj.read())
        except:
            # Do nothing, parsing failed.
            pass

    @classmethod
    def find_relevant_files(cls, path):
        # Go recursively and find howto's, readme's, hackings, installs.
        # If there are more of the same type then one, throw custom error as
        # written above.
        # Raise MultipleFilesException if files from ANDROID_FILES and
        # LINUX_FILES exist in the same dir.

        androidpaths = cls.dirEntries(path, files_list=settings.ANDROID_FILES)

        howto_path = os.path.join(path, HOWTO_PATH)
        howto_product_path = cls.getHowtoProductPath(path)
        androidpaths += cls.dirEntries(howto_path,
                                       files_list=settings.ANDROID_FILES)
        androidpaths += cls.dirEntries(howto_product_path,
                                       files_list=settings.ANDROID_FILES)

        ubuntupaths = cls.dirEntries(path, files_list=settings.LINUX_FILES)
        if len(androidpaths) > 0 and len(ubuntupaths) > 0:
            # Files from ANDROID_FILES and LINUX_FILES exist in the same dir
            raise MultipleFilesException(
                "Both Android and Ubuntu HOWTO files "
                "are found, which is unsupported.")
        else:
            if len(androidpaths) > 0:
                return androidpaths
            else:
                return ubuntupaths

    @classmethod
    def flatten(cls, l, ltypes=(list, tuple)):
        ltype = type(l)
        l = list(l)
        i = 0
        while i < len(l):
            while isinstance(l[i], ltypes):
                if not l[i]:
                    l.pop(i)
                    i -= 1
                    break
                else:
                    l[i:i + 1] = l[i]
            i += 1
        return ltype(l)

    @classmethod
    def dirEntries(cls, path, files_list=None):
        ''' Return a list of file names found in directory 'path'
            'files_list' are file names to match filenames. Matched file names
            are added to the list.
            If there are no additional arguments, all files found in the
            directory are added to the list.
        '''
        fileList = []
        if os.path.exists(path):
            for file in os.listdir(path):
                dirfile = os.path.join(path, file)
                if os.path.isfile(dirfile):
                    if not files_list:
                        fileList.append(dirfile)
                    else:
                        if file in cls.flatten(files_list):
                            fileList.append(dirfile)
        return fileList

    @classmethod
    def findall(cls, L, test):
        ''' Return indices of list items that pass the 'test'
        '''
        i = 0
        indices = []
        while(True):
            try:
                # next value in list passing the test
                nextvalue = filter(test, L[i:])[0]
                # add index of this value in the index list,
                # by searching the value in L[i:]
                indices.append(L.index(nextvalue, i))
                # iterate i, that is the next index from where to search
                i = indices[-1] + 1
            # when there is no further "good value", filter returns [],
            # hence there is an out of range exception
            except IndexError:
                return indices

    @classmethod
    def getHowtoProductPath(cls, path):
        """ Return the 'target/product/*/howto/ path.

        In case there is no such folder, return empty string.
        """
        howto_path = ""
        path = os.path.join(path, HOWTO_PRODUCT_PATH)
        if os.path.exists(path):
            for file in os.listdir(path):
                product_path = os.path.join(path, file)
                if os.path.isdir(product_path):
                    howto_path = os.path.join(product_path, HOWTO_PATH)
                    break

        return howto_path