gitar

Change view context for new stylesheet

Author
Maarten Vangeneugden
Date
Sept. 20, 2020, 9:09 p.m.
Hash
9c2a60bba78d07539089530006d4ddc3a05a3fc1
Parent
d4020260f4e2f4c5b3bc1d65e24db64f174b20f0
Modified file
views.py

views.py

1 addition and 2 deletions.

View changes Hide changes
1
1
    Copyright © 2016 Maarten "Vngngdn" Vangeneugden
2
2
3
3
    This program is free software: you can redistribute it and/or modify
4
4
    it under the terms of the GNU Affero General Public License as
5
5
    published by the Free Software Foundation, either version 3 of the
6
6
    License, or (at your option) any later version.
7
7
8
8
    This program is distributed in the hope that it will be useful,
9
9
    but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
11
    GNU Affero General Public License for more details.
12
12
13
13
    You should have received a copy of the GNU Affero General Public License
14
14
    along with this program. If not, see https://www.gnu.org/licenses/agpl.html.
15
15
"""
16
16
17
17
from django.shortcuts import get_object_or_404, render  # This allows to render the template with the view here. It's pretty cool and important.
18
18
from django.http import HttpResponseRedirect, HttpResponse
19
19
from django.urls import reverse
20
20
from .models import *
21
21
22
22
from .GitActions import RepoInfo
23
23
from django.utils.translation import ugettext as _
24
24
25
25
from django.utils.translation import ugettext as _
26
26
from git import Repo  # GitPython functionality.
27
27
import git
28
28
29
29
from .syntax import *
30
30
31
31
# First, I list some standard variables that are common for most of the sites of this app.
32
32
33
33
def footer_description():
34
34
    return _("Gitar is a simple web app that allows its users to easily share Git repos in combination with the Django framework.")
35
35
36
36
def footer_links():
37
37
    footer_links = [
38
38
            #['Source', 'OHGODHELPNOTDONEYET'],
39
39
            [_('Home page'), reverse('about-index')],
40
40
            [_('Source code'), reverse('gitar-repository', kwargs={'repository_name':'gitar'})],
41
41
            ]
42
42
    return footer_links
43
43
44
44
def standard_context():
45
45
    context = {
46
46
            'materialDesign_color': "blue-grey",
47
-
            'materialDesign_accentColor': "green",
48
-
            'navbar_title': "Gitar",
49
47
            'navbar_backArrow': False,
50
48
            'footer_title': "Gitar",
51
49
            'footer_description': footer_description(),
52
50
            'footer_links': footer_links(),
53
51
            }
+
52
            }
54
53
    return context
55
54
56
55
# From here, the actual views start.
57
56
def index(request):
58
57
    """ The start page of Gitar.
59
58
60
59
    The goal of this view, is to collect all the available repositories,
61
60
    including some additional information, such as programming language,
62
61
    license, description, ... in order to give a fast overview of the most
63
62
    prominent information.
64
63
    """
65
64
66
65
    # Collecting the available repositories:
67
66
    # Template:
68
67
    template = "gitar/index.djhtml"
69
68
    # Requesting the repositories:
70
69
    modelRepos = Repository.objects.all()
71
70
    # From here, we start collecting info about all the repositories:
72
71
    class BlankRepository: pass  # Blank object in which all data will be collected.
73
72
    repositories = []
74
73
    for modelRepo in modelRepos:
75
74
        repository = BlankRepository()
76
75
        # TODO: Find a way to add all of modelRepo's fields without having to
77
76
        # hardcode them. This is prone to errors and is redundant.
78
77
        repository.name = str(modelRepo)
79
78
        repository.programmingLanguage = modelRepo.programmingLanguage
80
79
        repository.license = modelRepo.license
81
80
        repository.description = RepoInfo.get_description(modelRepo)
82
81
83
82
        #gitRepo = Repo.init(modelRepo.directory(), bare=True)  # Connects to the Git Repo.
84
83
        # See tests.py, which assures all repositories exist. Tests are handy.
85
84
        #repository.description = gitRepo.description
86
85
        # This is mostly personal taste, but I like to show the amount of files.
87
86
        #repoTree = gitRepo.heads.master.commit.tree
88
87
        #repository.fileCount = len(repoTree.blobs)  # blobs are files.
89
88
        repositories.append(repository)
90
89
    # After that, I extend the standard context with the repositories:
91
90
    context = standard_context()
92
91
    context['repositories'] = repositories
93
92
    # And finally, sending everything back.
94
93
    return render(request, template, context)
95
94
96
95
def commit(request, repository, commit):
97
96
    pass  # TODO
98
97
99
98
def repositories(request, repository_name, branch="master"):
100
99
    # A repo's root is a directory by default, so this will automatically return
101
100
    # a directory view. But still, this is a bit nicer.
102
101
    return path_explorer(request, repository_name, branch, "")
103
102
104
103
def path_explorer(request, repository_name, branch, path):
105
104
    """ Checks whether the given path is a file or a directory, and calls the
106
105
    appropriate view function accordingly.
107
106
    """
108
107
    repository = RepoInfo.get_repository_object(repository_name)
109
108
    # From the GitPython documentation:
110
109
    # You can obtain the tree object of a repository, which is the directory of
111
110
    # that repo. This tree can be accessed as if it were a native Python list,
112
111
    # where the elements are the subdirectories and files. So, the idea to
113
112
    # determine whether a file, or a directory was requested, is simple:
114
113
    # 1. Split the path with "/" as seperator.
115
114
    # 2. Replace the current tree variable with the one retrieved from the
116
115
    # subtree element
117
116
    # 3. Repeat 2. until all parts of the given path are exhausted.
118
117
    # If we now still have a tree, we're looking at a directory, so display the
119
118
    # files (and subdirectories) of this directory.
120
119
    # Else, if we hit a blob, display the file contents.
121
120
    path_parts = path.split(sep="/")
122
121
    # FIXME: This is a bug at the URL regex part that I haven't been able to fix
123
122
    # yet. This serves as a temporary fix:
124
123
    # If the last part of the path is an empty string (which happens when the
125
124
    # last symbol was a '/'), remove that part from the list.
126
125
    # Of course, this is bad monkeypatching, but I suck at regex, so as long as
127
126
    # I don't find the solution, this'll have to do.
128
127
129
128
130
129
    #print(path_parts)
131
130
132
131
    if path_parts[len(path_parts)-1] == "":
133
132
        path_parts.pop()
134
133
135
134
    if len(path_parts) == 0:
136
135
        directory = repository.heads[branch].commit.tree
137
136
        return directory_view(request, repository_name, branch, path, directory)
138
137
139
138
    assert len(path_parts) != 0
140
139
141
140
    # FIXME: If the user gives a "<something>/../<somethingElse>", that should
142
141
    # become "<something>". Obviously, although I think that's done by default
143
142
    # already.
144
143
    directory = repository.heads[branch].commit.tree
145
144
    for i in range(len(path_parts)):
146
145
        subdirectories = directory.trees
147
146
        #if len(subdirectories) == 0:
148
147
            # This can't happen, as this would imply there is a directory inside
149
148
            # a file.
150
149
        #    assert False
151
150
        #else:
152
151
        for subdirectory in subdirectories:
153
152
            if subdirectory.name == path_parts[i]:
154
153
                directory = subdirectory
155
154
                #break  # Useless optimization
156
155
    # When there are no more directories to traverse, check if the last part of
157
156
    # the path is either a file, or a directory:
158
157
    blobs = directory.blobs
159
158
    #print(path_parts)
160
159
    last_part = path_parts[len(path_parts)-1]
161
160
    for blob in directory.blobs:
162
161
        #print(blob.name)
163
162
        if blob.name == last_part:
164
163
            file_blob = blob
165
164
            #print("Returning file view")
166
165
            return file_view(request, repository_name, branch, path, file_blob)
167
166
        else:
168
167
            pass
169
168
            #print("blob name: " + blob.name)
170
169
            #print("last part: " + last_part)
171
170
    return directory_view(request, repository_name, branch, path, directory)
172
171
173
172
def directory_view(request, repository_name, branch, path, directory):
174
173
    """ Collects the given directories's files and subdirectories, and renders a
175
174
    template to display this data.
176
175
    """
177
176
178
177
    # Collecting files in this directory
179
178
    repository = RepoInfo.get_repository_object(repository_name)
180
179
    files = []
181
180
    for file in directory.blobs:
182
181
        files.append({
183
182
            "name":file.name,
184
183
            "path":file.path,
185
184
            "commit":"",#FileInfo.last_commit(repository, file).hexsha[:20],
186
185
            })
187
186
    # Collecting commits for this branch
188
187
    commits = []
189
188
    for commit in repository.iter_commits(branch):
190
189
        commits.append({
191
190
            "hash":commit.hexsha[:20],
192
191
            "author":commit.author,
193
192
            "description":commit.summary,
194
193
            })
195
194
    # Collecting subdirectories
196
195
    subdirectories = []
197
196
    for subdirectory in directory.trees:
198
197
        subdirectories.append({
199
198
            "path":subdirectory.path,
200
199
            "name":subdirectory.name,
201
200
            })
202
201
    # Collecting rendering information:
203
202
    template = "gitar/directory.djhtml"
204
203
    context = standard_context()
205
204
    context["files"] = files
206
205
    context["subdirectories"] = subdirectories
207
206
    context["commits"] = commits
208
207
    context["branch"] = branch
209
208
    context["repository_name"] = repository_name
210
209
    context["repository_description"] = repository.description
211
210
    # Collection repo information
212
211
    for repo in Repository.objects.all():
213
212
        if str(repo) == repository_name:
214
213
            context["repository_language"] = repo.programmingLanguage
215
214
            context["repository_license"] = repo.license
216
215
            break
217
216
    branches = []
218
217
    for bbranch in repository.heads:
219
218
        branches.append(bbranch.name)
220
219
    context["branches"] = branches
221
220
    return render(request, template, context)
222
221
223
222
224
223
def file_view(request, repository_name, branch, path, file):
225
224
    """ Collects the file contents of the given file path, and returns it to the
226
225
    template, with the file contents already formatted in HTML using Pygments.
227
226
    """
228
227
229
228
    # Turning the file's contents in HTML ready output:
230
229
    raw_file_data = file.data_stream.read()
231
230
    html_code = code_to_HTML(raw_file_data, file.name)
232
231
    # Collecting rendering information:
233
232
    template = "gitar/file.djhtml"
234
233
    context = standard_context()
235
234
    context["content"] = html_code
236
235
    context["file_name"] = file.name
237
236
    context["repository_name"] = repository_name
238
237
    return render(request, template, context)
239
238
    
240
239