gitar

Rename templates with new typenames

Author
Maarten Vangeneugden
Date
Sept. 20, 2020, 10:28 p.m.
Hash
9c1649083407371e4e0f4a87a7d5055ea1956712
Parent
757ce47c23372f81564e095c137e32c1df4eaa6c
Modified files
templates/gitar/directory.html β†’ templates/gitar/directory.djhtml
templates/gitar/file.html β†’ templates/gitar/file.djhtml
templates/gitar/footer.html β†’ templates/gitar/footer.djhtml
templates/gitar/header.html β†’ templates/gitar/header.djhtml
templates/gitar/index.html β†’ templates/gitar/index.djhtml
templates/gitar/repositories.html β†’ templates/gitar/repositories.djhtml
views.py

templates/gitar/directory.html β†’ templates/gitar/directory.djhtml ΒΆ

0 additions and 0 deletions.

View changes Hide changes

templates/gitar/file.html β†’ templates/gitar/file.djhtml ΒΆ

0 additions and 0 deletions.

View changes Hide changes

templates/gitar/footer.html β†’ templates/gitar/footer.djhtml ΒΆ

0 additions and 0 deletions.

View changes Hide changes

templates/gitar/header.html β†’ templates/gitar/header.djhtml ΒΆ

0 additions and 0 deletions.

View changes Hide changes

templates/gitar/index.html β†’ templates/gitar/index.djhtml ΒΆ

1 addition and 1 deletion.

View changes Hide changes
1
-
{% load i18n %}
+
1
{% load i18n %}
2
2
3
3
{% block title %}{% trans "Gitar | Index page" %}{% endblock title %}
4
4
{% block description %}
5
5
{% trans "My personal answer to GitHub." %}
6
6
{% endblock description %}
7
7
{% block main %}
8
8
{% with mdac=materialDesign_accentColor %} {# You'll see why this is handy shortly. #}
9
9
{% with mdc=materialDesign_color %}
10
10
<div class="section {{ materialDesign_color }} lighten-2">
11
11
	<p class="flow-text container white-text">
12
12
		{% trans "Gitar is a simple web app to easily host Git repositories using the Django framework. %}
13
13
	</p>
14
14
</div>
15
15
<div class="container section">
16
16
    <h3 class="{{ materialDesign_color }}-text">{% trans "About Gitar" %}</h3>
17
17
    <p>
18
18
        {% blocktrans %}Gitar is a hobby project of me, to make it easy for
19
19
        people to scroll through the code I publish, in a read-only fashion. It
20
20
        makes use of
21
21
        <a class="{{ mdac }}-text text-accent-3" href="http://pygments.org/">Pygments</a>
22
22
        to read the source files, and apply the appropriate syntax coloring.
23
23
        {% endblocktrans %}
24
24
    </p>
25
25
    <p>
26
26
        {% blocktrans %}All repositories are automatically updated when changes
27
27
        have been pushed to the server, without any manual intervention from me.
28
28
        Special attention goes to clean URL design, adhering to web standards,
29
29
        and responsive design across all screen types.{% endblocktrans %}
30
30
    <p>
31
31
        {% blocktrans %}Gitar <b>is a project under development!</b>
32
32
        While it's certainly presentable, there's still a lot of room for improvement.<br />
33
33
        Also, if you happen to walk in while I'm working, it's possible you'll
34
34
        fall through the floor, so be warned =D{% endblocktrans %}
35
35
    </p>
36
36
</div>
37
37
<div class="container section">
38
38
    <h3 class="{{ materialDesign_color }}-text">{% trans "Public repositories" %}</h3>
39
39
		{% for repository in repositories %} {# ARGH DON'T YOU LOVE THE READABILITY #}
40
40
        <div class="row">
41
41
            <div class="col m3 valign-wrapper">
42
42
                <a class="valign waves-effect btn white {{ mdac }} accent-3" href="{% url 'gitar-repository' repository_name=repository.name %}">
43
43
                    {{ repository.name }}
44
44
                </a>
45
45
            </div>
46
46
            <div class="col m7">
47
47
                <p> {{ repository.description }} </p>
48
48
            </div>
49
49
            <div class="col m2">
50
50
            <ul>
51
51
                <li><i class="material-icons {{ mdac }}-text text-accent-3">code</i>
52
52
                    {{ repository.programmingLanguage }}</li>
53
53
                <!--<li><i class="material-icons">description</i> 
54
54
                    {{ repository.fileCount }}</li>-->
55
55
                <li><i class="material-icons {{ mdc }}-text">copyright</i>
56
56
                    {{ repository.license }}</li>
57
57
            </ul>
58
58
            </div>
59
59
        </div>
60
60
		{% endfor %}
61
61
	</div>
62
62
{% endwith %}
63
63
{% endwith %}
64
64
{% endblock main %}
65
65

templates/gitar/repositories.html β†’ templates/gitar/repositories.djhtml ΒΆ

0 additions and 0 deletions.

View changes Hide changes

views.py ΒΆ

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