Compare commits
No commits in common. "dcdb3d87be26266bd2e7bbf8019af1a0701299d0" and "1b6a9956c5c4cab05c7dd078ca649327221f1dc0" have entirely different histories.
dcdb3d87be
...
1b6a9956c5
7 changed files with 149 additions and 600 deletions
|
@ -3,7 +3,6 @@ from django.conf import settings
|
||||||
|
|
||||||
from .models import Think
|
from .models import Think
|
||||||
|
|
||||||
|
|
||||||
class CreateThinkForm(forms.ModelForm):
|
class CreateThinkForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Think
|
model = Think
|
||||||
|
@ -16,13 +15,11 @@ class CreateThinkForm(forms.ModelForm):
|
||||||
instance.root.mkdir(exist_ok=True,parents=True)
|
instance.root.mkdir(exist_ok=True,parents=True)
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
|
||||||
class RemixThinkForm(forms.ModelForm):
|
class RemixThinkForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Think
|
model = Think
|
||||||
fields = []
|
fields = []
|
||||||
|
|
||||||
|
|
||||||
class RenameThinkForm(forms.ModelForm):
|
class RenameThinkForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Think
|
model = Think
|
||||||
|
@ -52,7 +49,6 @@ class RenameThinkForm(forms.ModelForm):
|
||||||
instance = super().save(commit)
|
instance = super().save(commit)
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
|
||||||
class SaveFileForm(forms.ModelForm):
|
class SaveFileForm(forms.ModelForm):
|
||||||
path = forms.CharField()
|
path = forms.CharField()
|
||||||
content = forms.CharField(required=False, widget=forms.Textarea)
|
content = forms.CharField(required=False, widget=forms.Textarea)
|
||||||
|
@ -76,7 +72,6 @@ class SaveFileForm(forms.ModelForm):
|
||||||
|
|
||||||
return super().save(commit)
|
return super().save(commit)
|
||||||
|
|
||||||
|
|
||||||
class RenameFileForm(forms.ModelForm):
|
class RenameFileForm(forms.ModelForm):
|
||||||
path = forms.CharField()
|
path = forms.CharField()
|
||||||
newpath = forms.CharField()
|
newpath = forms.CharField()
|
||||||
|
@ -105,7 +100,6 @@ class RenameFileForm(forms.ModelForm):
|
||||||
|
|
||||||
return super().save(commit)
|
return super().save(commit)
|
||||||
|
|
||||||
|
|
||||||
class DeleteFileForm(forms.ModelForm):
|
class DeleteFileForm(forms.ModelForm):
|
||||||
path = forms.CharField()
|
path = forms.CharField()
|
||||||
|
|
||||||
|
@ -127,7 +121,6 @@ class DeleteFileForm(forms.ModelForm):
|
||||||
|
|
||||||
return super().save(commit)
|
return super().save(commit)
|
||||||
|
|
||||||
|
|
||||||
class RunCommandForm(forms.ModelForm):
|
class RunCommandForm(forms.ModelForm):
|
||||||
command = forms.CharField()
|
command = forms.CharField()
|
||||||
|
|
||||||
|
@ -135,51 +128,9 @@ class RunCommandForm(forms.ModelForm):
|
||||||
model = Think
|
model = Think
|
||||||
fields = []
|
fields = []
|
||||||
|
|
||||||
|
|
||||||
class GitCommitForm(forms.ModelForm):
|
class GitCommitForm(forms.ModelForm):
|
||||||
message = forms.CharField()
|
message = forms.CharField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Think
|
model = Think
|
||||||
fields = []
|
fields = []
|
||||||
|
|
||||||
|
|
||||||
class MultipleFileInput(forms.ClearableFileInput):
|
|
||||||
allow_multiple_selected = True
|
|
||||||
|
|
||||||
|
|
||||||
class MultipleFileField(forms.FileField):
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
kwargs.setdefault("widget", MultipleFileInput())
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
def clean(self, data, initial=None):
|
|
||||||
single_file_clean = super().clean
|
|
||||||
if isinstance(data, (list, tuple)):
|
|
||||||
result = [single_file_clean(d, initial) for d in data]
|
|
||||||
else:
|
|
||||||
result = [single_file_clean(data, initial)]
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
class UploadFileForm(forms.ModelForm):
|
|
||||||
files = MultipleFileField()
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = Think
|
|
||||||
fields = []
|
|
||||||
|
|
||||||
|
|
||||||
def save(self, commit=False):
|
|
||||||
think = self.instance
|
|
||||||
|
|
||||||
files = self.cleaned_data['files']
|
|
||||||
|
|
||||||
for uf in files:
|
|
||||||
path = think.file_path(uf.name)
|
|
||||||
print(uf, path)
|
|
||||||
with open(path, 'wb') as df:
|
|
||||||
for chunk in uf.chunks():
|
|
||||||
df.write(chunk)
|
|
||||||
|
|
||||||
return super().save(commit)
|
|
||||||
|
|
|
@ -26,19 +26,14 @@ class JJController:
|
||||||
)
|
)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def init_jj(self, force=False):
|
def init_jj(self):
|
||||||
print("Init jj")
|
print("Init jj")
|
||||||
res = self.run(['jj','git','remote','list'])
|
if not (self.root / '.jj').exists():
|
||||||
if force or not (self.root / '.jj').exists():
|
|
||||||
self.run(['jj','git','init'])
|
self.run(['jj','git','init'])
|
||||||
self.ignore_paths(['.make.*'])
|
self.ignore_paths(['.make.*'])
|
||||||
git_url = settings.GIT_REPO_URL_TEMPLATE.format(name=self.think.slug)
|
git_url = settings.GIT_REPO_URL_TEMPLATE.format(name=self.think.slug)
|
||||||
self.run(['jj','git','remote','add','origin', git_url])
|
self.run(['jj','git','remote','add','origin', git_url])
|
||||||
|
|
||||||
def clean_paths(self, paths):
|
|
||||||
paths = [self.root / p for p in paths]
|
|
||||||
return [str(p.relative_to(self.root)) for p in paths if p.is_relative_to(self.root)]
|
|
||||||
|
|
||||||
@ensure_jj
|
@ensure_jj
|
||||||
def ignore_paths(self, paths):
|
def ignore_paths(self, paths):
|
||||||
paths = self.clean_paths(paths)
|
paths = self.clean_paths(paths)
|
||||||
|
|
|
@ -109,13 +109,9 @@ input:not([type="hidden"]) ~ button {
|
||||||
|
|
||||||
input {
|
input {
|
||||||
border: thin solid currentColor;
|
border: thin solid currentColor;
|
||||||
height: 100%;
|
|
||||||
background: var(--default-background);
|
|
||||||
}
|
|
||||||
input[type="file"] {
|
|
||||||
font-size: 0.66rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.field {
|
.field {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--quarter-spacing);
|
gap: var(--quarter-spacing);
|
||||||
|
@ -243,12 +239,6 @@ input[type="file"] {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
& #file-form {
|
|
||||||
& > :is(img,video) {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
& code-editor {
|
& code-editor {
|
||||||
background: var(--default-background);
|
background: var(--default-background);
|
||||||
display: block;
|
display: block;
|
||||||
|
|
|
@ -5546,9 +5546,7 @@ var $author$project$App$Model = function (show_preview) {
|
||||||
return function (file_content) {
|
return function (file_content) {
|
||||||
return function (is_dir) {
|
return function (is_dir) {
|
||||||
return function (elm_packages) {
|
return function (elm_packages) {
|
||||||
return function (mime_type) {
|
return {command_to_run: command_to_run, commit_message: commit_message, content_changed: content_changed, csrf_token: csrf_token, editor_size: editor_size, elm_packages: elm_packages, file_content: file_content, file_path: file_path, files: files, is_dir: is_dir, jj_status: jj_status, log: log, preview_url: preview_url, selected_package: selected_package, show_log: show_log, show_preview: show_preview, slug: slug};
|
||||||
return {command_to_run: command_to_run, commit_message: commit_message, content_changed: content_changed, csrf_token: csrf_token, editor_size: editor_size, elm_packages: elm_packages, file_content: file_content, file_path: file_path, files: files, is_dir: is_dir, jj_status: jj_status, log: log, mime_type: mime_type, preview_url: preview_url, selected_package: selected_package, show_log: show_log, show_preview: show_preview, slug: slug};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -5566,10 +5564,6 @@ var $author$project$App$Model = function (show_preview) {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
var $danyx23$elm_mimetype$MimeType$PlainText = {$: 'PlainText'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Text = function (a) {
|
|
||||||
return {$: 'Text', a: a};
|
|
||||||
};
|
|
||||||
var $elm_community$json_extra$Json$Decode$Extra$andMap = $elm$json$Json$Decode$map2($elm$core$Basics$apR);
|
var $elm_community$json_extra$Json$Decode$Extra$andMap = $elm$json$Json$Decode$map2($elm$core$Basics$apR);
|
||||||
var $elm$json$Json$Decode$bool = _Json_decodeBool;
|
var $elm$json$Json$Decode$bool = _Json_decodeBool;
|
||||||
var $elm$core$Basics$composeR = F3(
|
var $elm$core$Basics$composeR = F3(
|
||||||
|
@ -5603,201 +5597,8 @@ var $author$project$App$decode_file_info = A4(
|
||||||
A2($elm$json$Json$Decode$field, 'name', $elm$json$Json$Decode$string),
|
A2($elm$json$Json$Decode$field, 'name', $elm$json$Json$Decode$string),
|
||||||
A2($elm$json$Json$Decode$field, 'is_dir', $elm$json$Json$Decode$bool),
|
A2($elm$json$Json$Decode$field, 'is_dir', $elm$json$Json$Decode$bool),
|
||||||
A2($elm$json$Json$Decode$field, 'path', $elm$json$Json$Decode$string));
|
A2($elm$json$Json$Decode$field, 'path', $elm$json$Json$Decode$string));
|
||||||
var $danyx23$elm_mimetype$MimeType$App = function (a) {
|
|
||||||
return {$: 'App', a: a};
|
|
||||||
};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Audio = function (a) {
|
|
||||||
return {$: 'Audio', a: a};
|
|
||||||
};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Avi = {$: 'Avi'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Css = {$: 'Css'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Excel = {$: 'Excel'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$ExcelXml = {$: 'ExcelXml'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Gif = {$: 'Gif'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Html = {$: 'Html'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Image = function (a) {
|
|
||||||
return {$: 'Image', a: a};
|
|
||||||
};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Jpeg = {$: 'Jpeg'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Json = {$: 'Json'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Mp3 = {$: 'Mp3'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Mp4 = {$: 'Mp4'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Mpeg = {$: 'Mpeg'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Ogg = {$: 'Ogg'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$OtherAudio = function (a) {
|
|
||||||
return {$: 'OtherAudio', a: a};
|
|
||||||
};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$OtherImage = function (a) {
|
|
||||||
return {$: 'OtherImage', a: a};
|
|
||||||
};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$OtherMimeType = function (a) {
|
|
||||||
return {$: 'OtherMimeType', a: a};
|
|
||||||
};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$OtherText = function (a) {
|
|
||||||
return {$: 'OtherText', a: a};
|
|
||||||
};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$OtherVideo = function (a) {
|
|
||||||
return {$: 'OtherVideo', a: a};
|
|
||||||
};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Pdf = {$: 'Pdf'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Png = {$: 'Png'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$PowerPoint = {$: 'PowerPoint'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$PowerPointXml = {$: 'PowerPointXml'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Quicktime = {$: 'Quicktime'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Video = function (a) {
|
|
||||||
return {$: 'Video', a: a};
|
|
||||||
};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Wav = {$: 'Wav'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Webm = {$: 'Webm'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Word = {$: 'Word'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$WordXml = {$: 'WordXml'};
|
|
||||||
var $danyx23$elm_mimetype$MimeType$Xml = {$: 'Xml'};
|
|
||||||
var $elm$core$String$toLower = _String_toLower;
|
|
||||||
var $danyx23$elm_mimetype$MimeType$parseMimeType = function (mimeString) {
|
|
||||||
var _v0 = $elm$core$String$toLower(mimeString);
|
|
||||||
switch (_v0) {
|
|
||||||
case '':
|
|
||||||
return $elm$core$Maybe$Nothing;
|
|
||||||
case 'image/jpeg':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Image($danyx23$elm_mimetype$MimeType$Jpeg));
|
|
||||||
case 'image/png':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Image($danyx23$elm_mimetype$MimeType$Png));
|
|
||||||
case 'image/gif':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Image($danyx23$elm_mimetype$MimeType$Gif));
|
|
||||||
case 'audio/mp3':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Audio($danyx23$elm_mimetype$MimeType$Mp3));
|
|
||||||
case 'audio/mpeg':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Audio($danyx23$elm_mimetype$MimeType$Mp3));
|
|
||||||
case 'audio/wav':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Audio($danyx23$elm_mimetype$MimeType$Wav));
|
|
||||||
case 'audio/ogg':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Audio($danyx23$elm_mimetype$MimeType$Ogg));
|
|
||||||
case 'video/mp4':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Video($danyx23$elm_mimetype$MimeType$Mp4));
|
|
||||||
case 'video/mpeg':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Video($danyx23$elm_mimetype$MimeType$Mpeg));
|
|
||||||
case 'video/quicktime':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Video($danyx23$elm_mimetype$MimeType$Quicktime));
|
|
||||||
case 'video/avi':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Video($danyx23$elm_mimetype$MimeType$Avi));
|
|
||||||
case 'video/webm':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Video($danyx23$elm_mimetype$MimeType$Webm));
|
|
||||||
case 'text/plain':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Text($danyx23$elm_mimetype$MimeType$PlainText));
|
|
||||||
case 'text/html':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Text($danyx23$elm_mimetype$MimeType$Html));
|
|
||||||
case 'text/css':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Text($danyx23$elm_mimetype$MimeType$Css));
|
|
||||||
case 'text/xml':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Text($danyx23$elm_mimetype$MimeType$Xml));
|
|
||||||
case 'application/json':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Text($danyx23$elm_mimetype$MimeType$Json));
|
|
||||||
case 'application/msword':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$App($danyx23$elm_mimetype$MimeType$Word));
|
|
||||||
case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$App($danyx23$elm_mimetype$MimeType$WordXml));
|
|
||||||
case 'application/vnd.ms-excel':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$App($danyx23$elm_mimetype$MimeType$Excel));
|
|
||||||
case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$App($danyx23$elm_mimetype$MimeType$ExcelXml));
|
|
||||||
case 'application/vnd.ms-powerpoint':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$App($danyx23$elm_mimetype$MimeType$PowerPoint));
|
|
||||||
case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$App($danyx23$elm_mimetype$MimeType$PowerPointXml));
|
|
||||||
case 'application/pdf':
|
|
||||||
return $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$App($danyx23$elm_mimetype$MimeType$Pdf));
|
|
||||||
default:
|
|
||||||
var lowerCaseMimeString = _v0;
|
|
||||||
return A2($elm$core$String$startsWith, 'image/', lowerCaseMimeString) ? $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Image(
|
|
||||||
$danyx23$elm_mimetype$MimeType$OtherImage(
|
|
||||||
A2(
|
|
||||||
$elm$core$String$dropLeft,
|
|
||||||
$elm$core$String$length('image/'),
|
|
||||||
lowerCaseMimeString)))) : (A2($elm$core$String$startsWith, 'audio/', lowerCaseMimeString) ? $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Audio(
|
|
||||||
$danyx23$elm_mimetype$MimeType$OtherAudio(
|
|
||||||
A2(
|
|
||||||
$elm$core$String$dropLeft,
|
|
||||||
$elm$core$String$length('audio/'),
|
|
||||||
lowerCaseMimeString)))) : (A2($elm$core$String$startsWith, 'video/', lowerCaseMimeString) ? $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Video(
|
|
||||||
$danyx23$elm_mimetype$MimeType$OtherVideo(
|
|
||||||
A2(
|
|
||||||
$elm$core$String$dropLeft,
|
|
||||||
$elm$core$String$length('video/'),
|
|
||||||
lowerCaseMimeString)))) : (A2($elm$core$String$startsWith, 'text/', lowerCaseMimeString) ? $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Text(
|
|
||||||
$danyx23$elm_mimetype$MimeType$OtherText(
|
|
||||||
A2(
|
|
||||||
$elm$core$String$dropLeft,
|
|
||||||
$elm$core$String$length('text/'),
|
|
||||||
lowerCaseMimeString)))) : $elm$core$Maybe$Just(
|
|
||||||
$danyx23$elm_mimetype$MimeType$OtherMimeType(lowerCaseMimeString)))));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var $elm$core$Maybe$withDefault = F2(
|
|
||||||
function (_default, maybe) {
|
|
||||||
if (maybe.$ === 'Just') {
|
|
||||||
var value = maybe.a;
|
|
||||||
return value;
|
|
||||||
} else {
|
|
||||||
return _default;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
var $author$project$App$decode_mime_type = A2(
|
|
||||||
$elm$json$Json$Decode$map,
|
|
||||||
A2(
|
|
||||||
$elm$core$Basics$composeR,
|
|
||||||
$danyx23$elm_mimetype$MimeType$parseMimeType,
|
|
||||||
$elm$core$Maybe$withDefault(
|
|
||||||
$danyx23$elm_mimetype$MimeType$Text($danyx23$elm_mimetype$MimeType$PlainText))),
|
|
||||||
$elm$json$Json$Decode$string);
|
|
||||||
var $author$project$App$NotLoaded = {$: 'NotLoaded'};
|
var $author$project$App$NotLoaded = {$: 'NotLoaded'};
|
||||||
var $author$project$App$init_model = {
|
var $author$project$App$init_model = {command_to_run: '', commit_message: '', content_changed: false, csrf_token: '', editor_size: 0.5, elm_packages: _List_Nil, file_content: 'The editor has not loaded successfully.', file_path: 'Oops!', files: _List_Nil, is_dir: false, jj_status: '', log: $author$project$App$NotLoaded, preview_url: '', selected_package: '', show_log: false, show_preview: true, slug: 'not-a-real-thing'};
|
||||||
command_to_run: '',
|
|
||||||
commit_message: '',
|
|
||||||
content_changed: false,
|
|
||||||
csrf_token: '',
|
|
||||||
editor_size: 0.5,
|
|
||||||
elm_packages: _List_Nil,
|
|
||||||
file_content: 'The editor has not loaded successfully.',
|
|
||||||
file_path: 'Oops!',
|
|
||||||
files: _List_Nil,
|
|
||||||
is_dir: false,
|
|
||||||
jj_status: '',
|
|
||||||
log: $author$project$App$NotLoaded,
|
|
||||||
mime_type: $danyx23$elm_mimetype$MimeType$Text($danyx23$elm_mimetype$MimeType$PlainText),
|
|
||||||
preview_url: '',
|
|
||||||
selected_package: '',
|
|
||||||
show_log: false,
|
|
||||||
show_preview: true,
|
|
||||||
slug: 'not-a-real-thing'
|
|
||||||
};
|
|
||||||
var $elm$json$Json$Decode$list = _Json_decodeList;
|
var $elm$json$Json$Decode$list = _Json_decodeList;
|
||||||
var $elm$json$Json$Decode$oneOf = _Json_oneOf;
|
var $elm$json$Json$Decode$oneOf = _Json_oneOf;
|
||||||
var $elm$core$Result$withDefault = F2(
|
var $elm$core$Result$withDefault = F2(
|
||||||
|
@ -5817,52 +5618,38 @@ var $author$project$App$load_flags = A2(
|
||||||
$elm$json$Json$Decode$oneOf(
|
$elm$json$Json$Decode$oneOf(
|
||||||
_List_fromArray(
|
_List_fromArray(
|
||||||
[
|
[
|
||||||
A2($elm$json$Json$Decode$field, 'mime_type', $author$project$App$decode_mime_type),
|
A2(
|
||||||
$elm$json$Json$Decode$succeed(
|
$elm$json$Json$Decode$field,
|
||||||
$danyx23$elm_mimetype$MimeType$Text($danyx23$elm_mimetype$MimeType$PlainText))
|
'elm_packages',
|
||||||
|
$elm$json$Json$Decode$list($author$project$App$decode_elm_package)),
|
||||||
|
$elm$json$Json$Decode$succeed(_List_Nil)
|
||||||
])),
|
])),
|
||||||
A2(
|
A2(
|
||||||
$elm_community$json_extra$Json$Decode$Extra$andMap,
|
$elm_community$json_extra$Json$Decode$Extra$andMap,
|
||||||
$elm$json$Json$Decode$oneOf(
|
A2($elm$json$Json$Decode$field, 'is_dir', $elm$json$Json$Decode$bool),
|
||||||
_List_fromArray(
|
|
||||||
[
|
|
||||||
A2(
|
|
||||||
$elm$json$Json$Decode$field,
|
|
||||||
'elm_packages',
|
|
||||||
$elm$json$Json$Decode$list($author$project$App$decode_elm_package)),
|
|
||||||
$elm$json$Json$Decode$succeed(_List_Nil)
|
|
||||||
])),
|
|
||||||
A2(
|
A2(
|
||||||
$elm_community$json_extra$Json$Decode$Extra$andMap,
|
$elm_community$json_extra$Json$Decode$Extra$andMap,
|
||||||
A2($elm$json$Json$Decode$field, 'is_dir', $elm$json$Json$Decode$bool),
|
A2($elm$json$Json$Decode$field, 'file_content', $elm$json$Json$Decode$string),
|
||||||
A2(
|
A2(
|
||||||
$elm_community$json_extra$Json$Decode$Extra$andMap,
|
$elm_community$json_extra$Json$Decode$Extra$andMap,
|
||||||
$elm$json$Json$Decode$oneOf(
|
A2($elm$json$Json$Decode$field, 'file_path', $elm$json$Json$Decode$string),
|
||||||
_List_fromArray(
|
|
||||||
[
|
|
||||||
A2($elm$json$Json$Decode$field, 'file_content', $elm$json$Json$Decode$string),
|
|
||||||
$elm$json$Json$Decode$succeed('')
|
|
||||||
])),
|
|
||||||
A2(
|
A2(
|
||||||
$elm_community$json_extra$Json$Decode$Extra$andMap,
|
$elm_community$json_extra$Json$Decode$Extra$andMap,
|
||||||
A2($elm$json$Json$Decode$field, 'file_path', $elm$json$Json$Decode$string),
|
A2(
|
||||||
|
$elm$json$Json$Decode$field,
|
||||||
|
'files',
|
||||||
|
$elm$json$Json$Decode$list($author$project$App$decode_file_info)),
|
||||||
A2(
|
A2(
|
||||||
$elm_community$json_extra$Json$Decode$Extra$andMap,
|
$elm_community$json_extra$Json$Decode$Extra$andMap,
|
||||||
A2(
|
A2($elm$json$Json$Decode$field, 'slug', $elm$json$Json$Decode$string),
|
||||||
$elm$json$Json$Decode$field,
|
|
||||||
'files',
|
|
||||||
$elm$json$Json$Decode$list($author$project$App$decode_file_info)),
|
|
||||||
A2(
|
A2(
|
||||||
$elm_community$json_extra$Json$Decode$Extra$andMap,
|
$elm_community$json_extra$Json$Decode$Extra$andMap,
|
||||||
A2($elm$json$Json$Decode$field, 'slug', $elm$json$Json$Decode$string),
|
A2($elm$json$Json$Decode$field, 'preview_url', $elm$json$Json$Decode$string),
|
||||||
A2(
|
A2(
|
||||||
$elm_community$json_extra$Json$Decode$Extra$andMap,
|
$elm_community$json_extra$Json$Decode$Extra$andMap,
|
||||||
A2($elm$json$Json$Decode$field, 'preview_url', $elm$json$Json$Decode$string),
|
A2($elm$json$Json$Decode$field, 'csrf_token', $elm$json$Json$Decode$string),
|
||||||
A2(
|
$elm$json$Json$Decode$succeed(
|
||||||
$elm_community$json_extra$Json$Decode$Extra$andMap,
|
A9($author$project$App$Model, $author$project$App$init_model.show_preview, $author$project$App$init_model.show_log, $author$project$App$init_model.editor_size, $author$project$App$init_model.content_changed, $author$project$App$init_model.log, $author$project$App$init_model.command_to_run, $author$project$App$init_model.selected_package, $author$project$App$init_model.jj_status, $author$project$App$init_model.commit_message))))))))))),
|
||||||
A2($elm$json$Json$Decode$field, 'csrf_token', $elm$json$Json$Decode$string),
|
|
||||||
$elm$json$Json$Decode$succeed(
|
|
||||||
A9($author$project$App$Model, $author$project$App$init_model.show_preview, $author$project$App$init_model.show_log, $author$project$App$init_model.editor_size, $author$project$App$init_model.content_changed, $author$project$App$init_model.log, $author$project$App$init_model.command_to_run, $author$project$App$init_model.selected_package, $author$project$App$init_model.jj_status, $author$project$App$init_model.commit_message)))))))))))),
|
|
||||||
$elm$core$Result$withDefault($author$project$App$init_model));
|
$elm$core$Result$withDefault($author$project$App$init_model));
|
||||||
var $author$project$App$SetLog = function (a) {
|
var $author$project$App$SetLog = function (a) {
|
||||||
return {$: 'SetLog', a: a};
|
return {$: 'SetLog', a: a};
|
||||||
|
@ -6660,8 +6447,8 @@ var $author$project$App$FileSaved = F2(
|
||||||
function (a, b) {
|
function (a, b) {
|
||||||
return {$: 'FileSaved', a: a, b: b};
|
return {$: 'FileSaved', a: a, b: b};
|
||||||
});
|
});
|
||||||
var $author$project$App$FilesUploaded = function (a) {
|
var $author$project$App$FileUploaded = function (a) {
|
||||||
return {$: 'FilesUploaded', a: a};
|
return {$: 'FileUploaded', a: a};
|
||||||
};
|
};
|
||||||
var $author$project$App$HttpError = function (a) {
|
var $author$project$App$HttpError = function (a) {
|
||||||
return {$: 'HttpError', a: a};
|
return {$: 'HttpError', a: a};
|
||||||
|
@ -6693,6 +6480,10 @@ var $author$project$App$SaveContent = function (a) {
|
||||||
var $author$project$App$SetFileContent = function (a) {
|
var $author$project$App$SetFileContent = function (a) {
|
||||||
return {$: 'SetFileContent', a: a};
|
return {$: 'SetFileContent', a: a};
|
||||||
};
|
};
|
||||||
|
var $author$project$App$UploadFile = F2(
|
||||||
|
function (a, b) {
|
||||||
|
return {$: 'UploadFile', a: a, b: b};
|
||||||
|
});
|
||||||
var $elm$core$Platform$Cmd$batch = _Platform_batch;
|
var $elm$core$Platform$Cmd$batch = _Platform_batch;
|
||||||
var $author$project$App$decode_command_response = $elm$json$Json$Decode$oneOf(
|
var $author$project$App$decode_command_response = $elm$json$Json$Decode$oneOf(
|
||||||
_List_fromArray(
|
_List_fromArray(
|
||||||
|
@ -6772,7 +6563,6 @@ var $author$project$App$fetch_jj_status = $elm$http$Http$get(
|
||||||
A2($elm$json$Json$Decode$field, 'status', $elm$json$Json$Decode$string)),
|
A2($elm$json$Json$Decode$field, 'status', $elm$json$Json$Decode$string)),
|
||||||
url: 'jj/status'
|
url: 'jj/status'
|
||||||
});
|
});
|
||||||
var $elm$http$Http$filePart = _Http_pair;
|
|
||||||
var $elm$url$Url$Builder$toQueryPair = function (_v0) {
|
var $elm$url$Url$Builder$toQueryPair = function (_v0) {
|
||||||
var key = _v0.a;
|
var key = _v0.a;
|
||||||
var value = _v0.b;
|
var value = _v0.b;
|
||||||
|
@ -6974,10 +6764,10 @@ var $author$project$App$update = F2(
|
||||||
case 'DropFiles':
|
case 'DropFiles':
|
||||||
var action = msg.a;
|
var action = msg.a;
|
||||||
var files = msg.b;
|
var files = msg.b;
|
||||||
if (action.$ === 'Content') {
|
var _v3 = $elm$core$List$head(files);
|
||||||
var _v4 = $elm$core$List$head(files);
|
if (_v3.$ === 'Just') {
|
||||||
if (_v4.$ === 'Just') {
|
var file = _v3.a;
|
||||||
var file = _v4.a;
|
if (action.$ === 'Content') {
|
||||||
return _Utils_Tuple2(
|
return _Utils_Tuple2(
|
||||||
model,
|
model,
|
||||||
A2(
|
A2(
|
||||||
|
@ -6985,47 +6775,51 @@ var $author$project$App$update = F2(
|
||||||
$author$project$App$SetFileContent,
|
$author$project$App$SetFileContent,
|
||||||
$elm$file$File$toString(file)));
|
$elm$file$File$toString(file)));
|
||||||
} else {
|
} else {
|
||||||
return _Utils_Tuple2(model, $elm$core$Platform$Cmd$none);
|
return _Utils_Tuple2(
|
||||||
|
model,
|
||||||
|
A2(
|
||||||
|
$elm$core$Task$perform,
|
||||||
|
$author$project$App$UploadFile(file),
|
||||||
|
$elm$file$File$toString(file)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return _Utils_Tuple2(
|
return _Utils_Tuple2(model, $elm$core$Platform$Cmd$none);
|
||||||
model,
|
}
|
||||||
$elm$http$Http$post(
|
case 'UploadFile':
|
||||||
{
|
var file = msg.a;
|
||||||
body: $elm$http$Http$multipartBody(
|
var contents = msg.b;
|
||||||
_Utils_ap(
|
return _Utils_Tuple2(
|
||||||
_List_fromArray(
|
model,
|
||||||
[
|
$elm$http$Http$post(
|
||||||
A2($elm$http$Http$stringPart, 'csrfmiddlewaretoken', model.csrf_token)
|
{
|
||||||
]),
|
body: $elm$http$Http$multipartBody(
|
||||||
|
_List_fromArray(
|
||||||
|
[
|
||||||
A2(
|
A2(
|
||||||
$elm$core$List$map,
|
$elm$http$Http$stringPart,
|
||||||
$elm$http$Http$filePart('files'),
|
'path',
|
||||||
files))),
|
$elm$file$File$name(file)),
|
||||||
expect: $elm$http$Http$expectWhatever(
|
A2($elm$http$Http$stringPart, 'content', contents),
|
||||||
function (r) {
|
A2($elm$http$Http$stringPart, 'csrfmiddlewaretoken', model.csrf_token)
|
||||||
if (r.$ === 'Ok') {
|
])),
|
||||||
return $author$project$App$FilesUploaded(files);
|
expect: $elm$http$Http$expectWhatever(
|
||||||
} else {
|
function (r) {
|
||||||
return $author$project$App$NoOp;
|
if (r.$ === 'Ok') {
|
||||||
}
|
return $author$project$App$FileUploaded(file);
|
||||||
}),
|
} else {
|
||||||
url: 'upload-files'
|
return $author$project$App$NoOp;
|
||||||
}));
|
}
|
||||||
}
|
}),
|
||||||
case 'FilesUploaded':
|
url: 'save-file'
|
||||||
var files = msg.a;
|
}));
|
||||||
if (files.b) {
|
case 'FileUploaded':
|
||||||
var file = files.a;
|
var file = msg.a;
|
||||||
var name = $elm$file$File$name(file);
|
var name = $elm$file$File$name(file);
|
||||||
var url = $author$project$App$file_edit_url(
|
var url = $author$project$App$file_edit_url(
|
||||||
{is_dir: false, name: name, path: name});
|
{is_dir: false, name: name, path: name});
|
||||||
return _Utils_Tuple2(
|
return _Utils_Tuple2(
|
||||||
model,
|
model,
|
||||||
$elm$browser$Browser$Navigation$load(url));
|
$elm$browser$Browser$Navigation$load(url));
|
||||||
} else {
|
|
||||||
return $author$project$App$nocmd(model);
|
|
||||||
}
|
|
||||||
case 'SetCommand':
|
case 'SetCommand':
|
||||||
var cmd = msg.a;
|
var cmd = msg.a;
|
||||||
return $author$project$App$nocmd(
|
return $author$project$App$nocmd(
|
||||||
|
@ -7390,14 +7184,12 @@ var $author$project$App$DropFiles = F2(
|
||||||
function (a, b) {
|
function (a, b) {
|
||||||
return {$: 'DropFiles', a: a, b: b};
|
return {$: 'DropFiles', a: a, b: b};
|
||||||
});
|
});
|
||||||
var $elm$html$Html$a = _VirtualDom_node('a');
|
|
||||||
var $elm$html$Html$Attributes$action = function (uri) {
|
var $elm$html$Html$Attributes$action = function (uri) {
|
||||||
return A2(
|
return A2(
|
||||||
$elm$html$Html$Attributes$stringProperty,
|
$elm$html$Html$Attributes$stringProperty,
|
||||||
'action',
|
'action',
|
||||||
_VirtualDom_noJavaScriptUri(uri));
|
_VirtualDom_noJavaScriptUri(uri));
|
||||||
};
|
};
|
||||||
var $elm$html$Html$audio = _VirtualDom_node('audio');
|
|
||||||
var $elm$file$File$decoder = _File_decoder;
|
var $elm$file$File$decoder = _File_decoder;
|
||||||
var $elm$html$Html$details = _VirtualDom_node('details');
|
var $elm$html$Html$details = _VirtualDom_node('details');
|
||||||
var $elm$core$List$drop = F2(
|
var $elm$core$List$drop = F2(
|
||||||
|
@ -7455,13 +7247,6 @@ var $elm$core$Dict$fromList = function (assocs) {
|
||||||
$elm$core$Dict$empty,
|
$elm$core$Dict$empty,
|
||||||
assocs);
|
assocs);
|
||||||
};
|
};
|
||||||
var $elm$html$Html$Attributes$href = function (url) {
|
|
||||||
return A2(
|
|
||||||
$elm$html$Html$Attributes$stringProperty,
|
|
||||||
'href',
|
|
||||||
_VirtualDom_noJavaScriptUri(url));
|
|
||||||
};
|
|
||||||
var $elm$html$Html$img = _VirtualDom_node('img');
|
|
||||||
var $elm$html$Html$nav = _VirtualDom_node('nav');
|
var $elm$html$Html$nav = _VirtualDom_node('nav');
|
||||||
var $elm$virtual_dom$VirtualDom$MayPreventDefault = function (a) {
|
var $elm$virtual_dom$VirtualDom$MayPreventDefault = function (a) {
|
||||||
return {$: 'MayPreventDefault', a: a};
|
return {$: 'MayPreventDefault', a: a};
|
||||||
|
@ -7475,14 +7260,16 @@ var $elm$html$Html$Events$preventDefaultOn = F2(
|
||||||
});
|
});
|
||||||
var $elm$html$Html$section = _VirtualDom_node('section');
|
var $elm$html$Html$section = _VirtualDom_node('section');
|
||||||
var $elm$html$Html$span = _VirtualDom_node('span');
|
var $elm$html$Html$span = _VirtualDom_node('span');
|
||||||
var $elm$html$Html$Attributes$src = function (url) {
|
|
||||||
return A2(
|
|
||||||
$elm$html$Html$Attributes$stringProperty,
|
|
||||||
'src',
|
|
||||||
_VirtualDom_noJavaScriptOrHtmlUri(url));
|
|
||||||
};
|
|
||||||
var $elm$html$Html$summary = _VirtualDom_node('summary');
|
var $elm$html$Html$summary = _VirtualDom_node('summary');
|
||||||
var $elm$html$Html$video = _VirtualDom_node('video');
|
var $elm$core$Maybe$withDefault = F2(
|
||||||
|
function (_default, maybe) {
|
||||||
|
if (maybe.$ === 'Just') {
|
||||||
|
var value = maybe.a;
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return _default;
|
||||||
|
}
|
||||||
|
});
|
||||||
var $author$project$App$editor_pane = function (model) {
|
var $author$project$App$editor_pane = function (model) {
|
||||||
var languages = $elm$core$Dict$fromList(
|
var languages = $elm$core$Dict$fromList(
|
||||||
_List_fromArray(
|
_List_fromArray(
|
||||||
|
@ -7494,7 +7281,6 @@ var $author$project$App$editor_pane = function (model) {
|
||||||
_Utils_Tuple2('R', 'r'),
|
_Utils_Tuple2('R', 'r'),
|
||||||
_Utils_Tuple2('elm', 'elm')
|
_Utils_Tuple2('elm', 'elm')
|
||||||
]));
|
]));
|
||||||
var file_path = 'file/' + model.file_path;
|
|
||||||
var extension = A2(
|
var extension = A2(
|
||||||
$elm$core$Maybe$withDefault,
|
$elm$core$Maybe$withDefault,
|
||||||
'',
|
'',
|
||||||
|
@ -7662,111 +7448,57 @@ var $author$project$App$editor_pane = function (model) {
|
||||||
$elm$html$Html$Attributes$method('POST'),
|
$elm$html$Html$Attributes$method('POST'),
|
||||||
$elm$html$Html$Attributes$action('save-file')
|
$elm$html$Html$Attributes$action('save-file')
|
||||||
]),
|
]),
|
||||||
function () {
|
_List_fromArray(
|
||||||
var _v0 = model.mime_type;
|
[
|
||||||
switch (_v0.$) {
|
A3(
|
||||||
case 'Text':
|
$elm$html$Html$node,
|
||||||
return _List_fromArray(
|
'code-editor',
|
||||||
[
|
_List_fromArray(
|
||||||
A3(
|
[
|
||||||
$elm$html$Html$node,
|
A2(
|
||||||
'code-editor',
|
$elm$html$Html$Events$on,
|
||||||
_List_fromArray(
|
'change',
|
||||||
[
|
A2(
|
||||||
A2(
|
$elm$json$Json$Decode$map,
|
||||||
$elm$html$Html$Events$on,
|
$author$project$App$SetFileContent,
|
||||||
'change',
|
|
||||||
A2(
|
|
||||||
$elm$json$Json$Decode$map,
|
|
||||||
$author$project$App$SetFileContent,
|
|
||||||
A2(
|
|
||||||
$elm$json$Json$Decode$at,
|
|
||||||
_List_fromArray(
|
|
||||||
['target', 'value']),
|
|
||||||
$elm$json$Json$Decode$string))),
|
|
||||||
A2($elm$html$Html$Attributes$attribute, 'content', model.file_content),
|
|
||||||
A2($elm$html$Html$Attributes$attribute, 'language', language)
|
|
||||||
]),
|
|
||||||
_List_fromArray(
|
|
||||||
[
|
|
||||||
$elm$html$Html$text(model.file_content)
|
|
||||||
])),
|
|
||||||
A2(
|
A2(
|
||||||
$elm$html$Html$input,
|
$elm$json$Json$Decode$at,
|
||||||
_List_fromArray(
|
_List_fromArray(
|
||||||
[
|
['target', 'value']),
|
||||||
$elm$html$Html$Attributes$name('path'),
|
$elm$json$Json$Decode$string))),
|
||||||
$elm$html$Html$Attributes$value(model.file_path),
|
A2($elm$html$Html$Attributes$attribute, 'content', model.file_content),
|
||||||
$elm$html$Html$Attributes$type_('hidden')
|
A2($elm$html$Html$Attributes$attribute, 'language', language)
|
||||||
]),
|
]),
|
||||||
_List_Nil),
|
_List_fromArray(
|
||||||
A2(
|
[
|
||||||
$elm$html$Html$input,
|
$elm$html$Html$text(model.file_content)
|
||||||
_List_fromArray(
|
])),
|
||||||
[
|
A2(
|
||||||
$elm$html$Html$Attributes$name('content'),
|
$elm$html$Html$input,
|
||||||
$elm$html$Html$Attributes$value(model.file_content),
|
_List_fromArray(
|
||||||
$elm$html$Html$Attributes$type_('hidden')
|
[
|
||||||
]),
|
$elm$html$Html$Attributes$name('path'),
|
||||||
_List_Nil)
|
$elm$html$Html$Attributes$value(model.file_path),
|
||||||
]);
|
$elm$html$Html$Attributes$type_('hidden')
|
||||||
case 'Image':
|
]),
|
||||||
return _List_fromArray(
|
_List_Nil),
|
||||||
[
|
A2(
|
||||||
A2(
|
$elm$html$Html$input,
|
||||||
$elm$html$Html$img,
|
_List_fromArray(
|
||||||
_List_fromArray(
|
[
|
||||||
[
|
$elm$html$Html$Attributes$name('content'),
|
||||||
$elm$html$Html$Attributes$src(file_path)
|
$elm$html$Html$Attributes$value(model.file_content),
|
||||||
]),
|
$elm$html$Html$Attributes$type_('hidden')
|
||||||
_List_Nil)
|
]),
|
||||||
]);
|
_List_Nil)
|
||||||
case 'Audio':
|
]))
|
||||||
return _List_fromArray(
|
|
||||||
[
|
|
||||||
A2(
|
|
||||||
$elm$html$Html$audio,
|
|
||||||
_List_fromArray(
|
|
||||||
[
|
|
||||||
$elm$html$Html$Attributes$src(file_path),
|
|
||||||
A2($elm$html$Html$Attributes$attribute, 'controls', '')
|
|
||||||
]),
|
|
||||||
_List_Nil)
|
|
||||||
]);
|
|
||||||
case 'Video':
|
|
||||||
return _List_fromArray(
|
|
||||||
[
|
|
||||||
A2(
|
|
||||||
$elm$html$Html$video,
|
|
||||||
_List_fromArray(
|
|
||||||
[
|
|
||||||
$elm$html$Html$Attributes$src(file_path),
|
|
||||||
A2($elm$html$Html$Attributes$attribute, 'controls', '')
|
|
||||||
]),
|
|
||||||
_List_Nil)
|
|
||||||
]);
|
|
||||||
default:
|
|
||||||
return _List_fromArray(
|
|
||||||
[
|
|
||||||
A2(
|
|
||||||
$elm$html$Html$a,
|
|
||||||
_List_fromArray(
|
|
||||||
[
|
|
||||||
$elm$html$Html$Attributes$href(file_path)
|
|
||||||
]),
|
|
||||||
_List_fromArray(
|
|
||||||
[
|
|
||||||
$elm$html$Html$text('Download')
|
|
||||||
]))
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}())
|
|
||||||
]));
|
]));
|
||||||
};
|
};
|
||||||
var $elm$core$String$fromFloat = _String_fromNumber;
|
var $elm$core$String$fromFloat = _String_fromNumber;
|
||||||
var $author$project$App$SetEditorSize = function (a) {
|
var $author$project$App$SetEditorSize = function (a) {
|
||||||
return {$: 'SetEditorSize', a: a};
|
return {$: 'SetEditorSize', a: a};
|
||||||
};
|
};
|
||||||
|
var $elm$html$Html$a = _VirtualDom_node('a');
|
||||||
var $elm$core$Basics$round = _Basics_round;
|
var $elm$core$Basics$round = _Basics_round;
|
||||||
var $author$project$App$as_percentage = function (amount) {
|
var $author$project$App$as_percentage = function (amount) {
|
||||||
return $elm$core$String$fromInt(
|
return $elm$core$String$fromInt(
|
||||||
|
@ -7776,6 +7508,12 @@ var $elm$html$Html$datalist = _VirtualDom_node('datalist');
|
||||||
var $elm$json$Json$Decode$float = _Json_decodeFloat;
|
var $elm$json$Json$Decode$float = _Json_decodeFloat;
|
||||||
var $elm$html$Html$h1 = _VirtualDom_node('h1');
|
var $elm$html$Html$h1 = _VirtualDom_node('h1');
|
||||||
var $elm$html$Html$header = _VirtualDom_node('header');
|
var $elm$html$Html$header = _VirtualDom_node('header');
|
||||||
|
var $elm$html$Html$Attributes$href = function (url) {
|
||||||
|
return A2(
|
||||||
|
$elm$html$Html$Attributes$stringProperty,
|
||||||
|
'href',
|
||||||
|
_VirtualDom_noJavaScriptUri(url));
|
||||||
|
};
|
||||||
var $author$project$App$link = F2(
|
var $author$project$App$link = F2(
|
||||||
function (url, text) {
|
function (url, text) {
|
||||||
return A2(
|
return A2(
|
||||||
|
@ -7794,52 +7532,6 @@ var $elm$html$Html$Attributes$max = $elm$html$Html$Attributes$stringProperty('ma
|
||||||
var $elm$html$Html$Attributes$min = $elm$html$Html$Attributes$stringProperty('min');
|
var $elm$html$Html$Attributes$min = $elm$html$Html$Attributes$stringProperty('min');
|
||||||
var $elm$html$Html$option = _VirtualDom_node('option');
|
var $elm$html$Html$option = _VirtualDom_node('option');
|
||||||
var $elm$html$Html$output = _VirtualDom_node('output');
|
var $elm$html$Html$output = _VirtualDom_node('output');
|
||||||
var $elm$core$List$any = F2(
|
|
||||||
function (isOkay, list) {
|
|
||||||
any:
|
|
||||||
while (true) {
|
|
||||||
if (!list.b) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
var x = list.a;
|
|
||||||
var xs = list.b;
|
|
||||||
if (isOkay(x)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
var $temp$isOkay = isOkay,
|
|
||||||
$temp$list = xs;
|
|
||||||
isOkay = $temp$isOkay;
|
|
||||||
list = $temp$list;
|
|
||||||
continue any;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
var $elm$core$List$member = F2(
|
|
||||||
function (x, xs) {
|
|
||||||
return A2(
|
|
||||||
$elm$core$List$any,
|
|
||||||
function (a) {
|
|
||||||
return _Utils_eq(a, x);
|
|
||||||
},
|
|
||||||
xs);
|
|
||||||
});
|
|
||||||
var $author$project$App$suffix = A2(
|
|
||||||
$elm$core$Basics$composeR,
|
|
||||||
$elm$core$String$split('.'),
|
|
||||||
A2(
|
|
||||||
$elm$core$Basics$composeR,
|
|
||||||
$elm$core$List$reverse,
|
|
||||||
A2(
|
|
||||||
$elm$core$Basics$composeR,
|
|
||||||
$elm$core$List$head,
|
|
||||||
$elm$core$Maybe$withDefault(''))));
|
|
||||||
var $author$project$App$preview_url = function (model) {
|
|
||||||
var page_suffixes = _List_fromArray(
|
|
||||||
['html', 'php']);
|
|
||||||
var file_suffix = $author$project$App$suffix(model.file_path);
|
|
||||||
return A2($elm$core$List$member, file_suffix, page_suffixes) ? (model.preview_url + ('/' + model.file_path)) : model.preview_url;
|
|
||||||
};
|
|
||||||
var $elm$html$Html$Attributes$step = function (n) {
|
var $elm$html$Html$Attributes$step = function (n) {
|
||||||
return A2($elm$html$Html$Attributes$stringProperty, 'step', n);
|
return A2($elm$html$Html$Attributes$stringProperty, 'step', n);
|
||||||
};
|
};
|
||||||
|
@ -7871,8 +7563,7 @@ var $author$project$App$header = function (model) {
|
||||||
_List_fromArray(
|
_List_fromArray(
|
||||||
[
|
[
|
||||||
$elm$html$Html$Attributes$target('preview'),
|
$elm$html$Html$Attributes$target('preview'),
|
||||||
$elm$html$Html$Attributes$href(
|
$elm$html$Html$Attributes$href(model.preview_url)
|
||||||
$author$project$App$preview_url(model))
|
|
||||||
]),
|
]),
|
||||||
_List_fromArray(
|
_List_fromArray(
|
||||||
[
|
[
|
||||||
|
@ -8196,7 +7887,6 @@ var $author$project$App$SetCommand = function (a) {
|
||||||
};
|
};
|
||||||
var $author$project$App$ShowCommitModal = {$: 'ShowCommitModal'};
|
var $author$project$App$ShowCommitModal = {$: 'ShowCommitModal'};
|
||||||
var $author$project$App$Upload = {$: 'Upload'};
|
var $author$project$App$Upload = {$: 'Upload'};
|
||||||
var $elm$html$Html$Attributes$enctype = $elm$html$Html$Attributes$stringProperty('enctype');
|
|
||||||
var $elm$html$Html$li = _VirtualDom_node('li');
|
var $elm$html$Html$li = _VirtualDom_node('li');
|
||||||
var $elm$core$Basics$not = _Basics_not;
|
var $elm$core$Basics$not = _Basics_not;
|
||||||
var $elm$html$Html$Events$onClick = function (msg) {
|
var $elm$html$Html$Events$onClick = function (msg) {
|
||||||
|
@ -8376,50 +8066,6 @@ var $author$project$App$main_nav = function (model) {
|
||||||
$elm$html$Html$text('Run')
|
$elm$html$Html$text('Run')
|
||||||
]))
|
]))
|
||||||
])),
|
])),
|
||||||
A3(
|
|
||||||
$author$project$App$form,
|
|
||||||
model,
|
|
||||||
_List_fromArray(
|
|
||||||
[
|
|
||||||
$elm$html$Html$Attributes$method('POST'),
|
|
||||||
$elm$html$Html$Attributes$action('upload-files'),
|
|
||||||
$elm$html$Html$Attributes$enctype('multipart/form-data'),
|
|
||||||
A2(
|
|
||||||
$elm$html$Html$Events$stopPropagationOn,
|
|
||||||
'drop',
|
|
||||||
$elm$json$Json$Decode$succeed(
|
|
||||||
_Utils_Tuple2($author$project$App$NoOp, true))),
|
|
||||||
A2(
|
|
||||||
$elm$html$Html$Events$stopPropagationOn,
|
|
||||||
'dragover',
|
|
||||||
$elm$json$Json$Decode$succeed(
|
|
||||||
_Utils_Tuple2($author$project$App$NoOp, true)))
|
|
||||||
]),
|
|
||||||
_List_fromArray(
|
|
||||||
[
|
|
||||||
A2(
|
|
||||||
$elm$html$Html$input,
|
|
||||||
_List_fromArray(
|
|
||||||
[
|
|
||||||
A2($elm$html$Html$Attributes$attribute, 'aria-labelledby', 'upload-files-button'),
|
|
||||||
$elm$html$Html$Attributes$type_('file'),
|
|
||||||
A2($elm$html$Html$Attributes$attribute, 'multiple', ''),
|
|
||||||
$elm$html$Html$Attributes$id('id_files'),
|
|
||||||
$elm$html$Html$Attributes$name('files')
|
|
||||||
]),
|
|
||||||
_List_Nil),
|
|
||||||
A2(
|
|
||||||
$elm$html$Html$button,
|
|
||||||
_List_fromArray(
|
|
||||||
[
|
|
||||||
$elm$html$Html$Attributes$id('upload-files-button'),
|
|
||||||
$elm$html$Html$Attributes$type_('submit')
|
|
||||||
]),
|
|
||||||
_List_fromArray(
|
|
||||||
[
|
|
||||||
$elm$html$Html$text('Upload')
|
|
||||||
]))
|
|
||||||
])),
|
|
||||||
(A2($elm$core$String$right, 4, model.file_path) === '.elm') ? A3(
|
(A2($elm$core$String$right, 4, model.file_path) === '.elm') ? A3(
|
||||||
$author$project$App$form,
|
$author$project$App$form,
|
||||||
model,
|
model,
|
||||||
|
@ -8521,6 +8167,12 @@ var $author$project$App$TogglePreview = function (a) {
|
||||||
return {$: 'TogglePreview', a: a};
|
return {$: 'TogglePreview', a: a};
|
||||||
};
|
};
|
||||||
var $elm$html$Html$iframe = _VirtualDom_node('iframe');
|
var $elm$html$Html$iframe = _VirtualDom_node('iframe');
|
||||||
|
var $elm$html$Html$Attributes$src = function (url) {
|
||||||
|
return A2(
|
||||||
|
$elm$html$Html$Attributes$stringProperty,
|
||||||
|
'src',
|
||||||
|
_VirtualDom_noJavaScriptOrHtmlUri(url));
|
||||||
|
};
|
||||||
var $author$project$App$preview_pane = function (model) {
|
var $author$project$App$preview_pane = function (model) {
|
||||||
return A2(
|
return A2(
|
||||||
$elm$html$Html$details,
|
$elm$html$Html$details,
|
||||||
|
@ -8558,8 +8210,7 @@ var $author$project$App$preview_pane = function (model) {
|
||||||
_List_fromArray(
|
_List_fromArray(
|
||||||
[
|
[
|
||||||
$elm$html$Html$Attributes$id('preview-frame'),
|
$elm$html$Html$Attributes$id('preview-frame'),
|
||||||
$elm$html$Html$Attributes$src(
|
$elm$html$Html$Attributes$src(model.preview_url)
|
||||||
$author$project$App$preview_url(model))
|
|
||||||
]),
|
]),
|
||||||
_List_Nil)
|
_List_Nil)
|
||||||
]) : _List_Nil));
|
]) : _List_Nil));
|
||||||
|
|
|
@ -8,12 +8,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
body {
|
|
||||||
--background: hsl(70,100%,8%);
|
--background: hsl(70,100%,8%);
|
||||||
--default-background: black;
|
|
||||||
--color: white;
|
--color: white;
|
||||||
--button-bg: #333;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
|
|
|
@ -12,7 +12,6 @@ urlpatterns = [
|
||||||
path('think/<slug:slug>/rename-file', RenameFileView.as_view(), name='rename_file'),
|
path('think/<slug:slug>/rename-file', RenameFileView.as_view(), name='rename_file'),
|
||||||
path('think/<slug:slug>/delete-file', DeleteFileView.as_view(), name='delete_file'),
|
path('think/<slug:slug>/delete-file', DeleteFileView.as_view(), name='delete_file'),
|
||||||
path('think/<slug:slug>/run-command', RunCommandView.as_view(), name='run_command'),
|
path('think/<slug:slug>/run-command', RunCommandView.as_view(), name='run_command'),
|
||||||
path('think/<slug:slug>/upload-files', UploadFileView.as_view(), name='upload_files'),
|
|
||||||
path('think/<slug:slug>/log', LogView.as_view(), name='log'),
|
path('think/<slug:slug>/log', LogView.as_view(), name='log'),
|
||||||
path('think/<slug:slug>/jj/status', JJStatusView.as_view(), name='jj_status'),
|
path('think/<slug:slug>/jj/status', JJStatusView.as_view(), name='jj_status'),
|
||||||
path('think/<slug:slug>/jj/commit', JJCommitView.as_view(), name='jj_commit'),
|
path('think/<slug:slug>/jj/commit', JJCommitView.as_view(), name='jj_commit'),
|
||||||
|
|
|
@ -6,7 +6,6 @@ from django.views import generic
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from itertools import groupby
|
from itertools import groupby
|
||||||
import json
|
import json
|
||||||
import mimetypes
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import shutil
|
import shutil
|
||||||
import shlex
|
import shlex
|
||||||
|
@ -17,7 +16,6 @@ from .make import ThingMaker
|
||||||
from .models import Think
|
from .models import Think
|
||||||
from .random_slug import random_slug
|
from .random_slug import random_slug
|
||||||
|
|
||||||
|
|
||||||
class LoginRequiredMixin(AccessMixin):
|
class LoginRequiredMixin(AccessMixin):
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
if not request.user.is_authenticated:
|
if not request.user.is_authenticated:
|
||||||
|
@ -27,12 +25,10 @@ class LoginRequiredMixin(AccessMixin):
|
||||||
|
|
||||||
return super().dispatch(request, *args, **kwargs)
|
return super().dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class ThinkMixin(LoginRequiredMixin):
|
class ThinkMixin(LoginRequiredMixin):
|
||||||
model = Think
|
model = Think
|
||||||
context_object_name = 'think'
|
context_object_name = 'think'
|
||||||
|
|
||||||
|
|
||||||
class IndexView(ThinkMixin, generic.ListView):
|
class IndexView(ThinkMixin, generic.ListView):
|
||||||
template_name = 'thinks/index.html'
|
template_name = 'thinks/index.html'
|
||||||
|
|
||||||
|
@ -54,12 +50,10 @@ class IndexView(ThinkMixin, generic.ListView):
|
||||||
return JsonResponse({'templates': [t.as_json() for t in context['templates']], 'thinks': [t.as_json() for t in context['thinks']]})
|
return JsonResponse({'templates': [t.as_json() for t in context['templates']], 'thinks': [t.as_json() for t in context['thinks']]})
|
||||||
return super().get(request, *args, **kwargs)
|
return super().get(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class CreateThinkView(ThinkMixin, generic.CreateView):
|
class CreateThinkView(ThinkMixin, generic.CreateView):
|
||||||
template_name = 'thinks/new.html'
|
template_name = 'thinks/new.html'
|
||||||
form_class = forms.CreateThinkForm
|
form_class = forms.CreateThinkForm
|
||||||
|
|
||||||
|
|
||||||
class RemixThinkView(ThinkMixin, generic.UpdateView):
|
class RemixThinkView(ThinkMixin, generic.UpdateView):
|
||||||
template_name = 'thinks/remix.html'
|
template_name = 'thinks/remix.html'
|
||||||
form_class = forms.RemixThinkForm
|
form_class = forms.RemixThinkForm
|
||||||
|
@ -85,7 +79,6 @@ class RemixThinkView(ThinkMixin, generic.UpdateView):
|
||||||
return redirect(think.get_absolute_url())
|
return redirect(think.get_absolute_url())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ThinkView(ThinkMixin, generic.DetailView):
|
class ThinkView(ThinkMixin, generic.DetailView):
|
||||||
template_name = "thinks/think.html"
|
template_name = "thinks/think.html"
|
||||||
|
|
||||||
|
@ -131,37 +124,28 @@ class ThinkView(ThinkMixin, generic.DetailView):
|
||||||
|
|
||||||
files = sorted(files, key=lambda x: x['name'].lower())
|
files = sorted(files, key=lambda x: x['name'].lower())
|
||||||
|
|
||||||
|
if path is not None and path.is_file():
|
||||||
|
with open(path) as f:
|
||||||
|
content = f.read()
|
||||||
|
else:
|
||||||
|
content = ''
|
||||||
|
|
||||||
data = context['think_editor_data'] = {
|
data = context['think_editor_data'] = {
|
||||||
'preview_url': think.get_static_url(),
|
'preview_url': think.get_static_url(),
|
||||||
'slug': think.slug,
|
'slug': think.slug,
|
||||||
'files': files,
|
'files': files,
|
||||||
'file_path': str(relpath),
|
'file_path': str(relpath),
|
||||||
|
'file_content': content,
|
||||||
'is_dir': path is None or path.is_dir(),
|
'is_dir': path is None or path.is_dir(),
|
||||||
'no_preview': self.request.GET.get('no-preview') is not None,
|
'no_preview': self.request.GET.get('no-preview') is not None,
|
||||||
}
|
}
|
||||||
|
|
||||||
if path is not None and path.is_file():
|
|
||||||
mime_types = {
|
|
||||||
'.elm': 'text/application+elm',
|
|
||||||
}
|
|
||||||
mime_type, encoding = mimetypes.guess_type(path)
|
|
||||||
if mime_type is None:
|
|
||||||
mime_type = mime_types.get(path.suffix, 'text/plain')
|
|
||||||
category, filetype = mime_type.split('/') if mime_type is not None else ('text', 'plain')
|
|
||||||
binary_categories = ['audio', 'video', 'image']
|
|
||||||
is_binary = category in binary_categories and mime_type != 'image/svg+xml'
|
|
||||||
data['mime_type'] = mime_type
|
|
||||||
if not is_binary:
|
|
||||||
with open(path) as f:
|
|
||||||
data['file_content'] = f.read()
|
|
||||||
|
|
||||||
if path is not None and path.suffix == '.elm':
|
if path is not None and path.suffix == '.elm':
|
||||||
with open('public/elm-packages.json') as f:
|
with open('public/elm-packages.json') as f:
|
||||||
data['elm_packages'] = json.load(f)
|
data['elm_packages'] = json.load(f)
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class RenameThinkView(ThinkMixin, generic.UpdateView):
|
class RenameThinkView(ThinkMixin, generic.UpdateView):
|
||||||
form_class = forms.RenameThinkForm
|
form_class = forms.RenameThinkForm
|
||||||
template_name = 'thinks/rename.html'
|
template_name = 'thinks/rename.html'
|
||||||
|
@ -176,22 +160,18 @@ class RenameThinkView(ThinkMixin, generic.UpdateView):
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class DeleteThinkView(ThinkMixin, generic.DeleteView):
|
class DeleteThinkView(ThinkMixin, generic.DeleteView):
|
||||||
template_name = 'thinks/delete.html'
|
template_name = 'thinks/delete.html'
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
return reverse('index')
|
return reverse('index')
|
||||||
|
|
||||||
|
|
||||||
class ReadFileView(ThinkMixin, generic.DetailView):
|
class ReadFileView(ThinkMixin, generic.DetailView):
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
think = self.get_object()
|
think = self.get_object()
|
||||||
relpath = self.kwargs['path']
|
relpath = self.kwargs['path']
|
||||||
path = think.root / relpath
|
path = think.root / relpath
|
||||||
if not path.is_relative_to(think.root):
|
print(path)
|
||||||
raise Exception(f"Bad path: {relpath}")
|
|
||||||
return redirect(think.get_static_url() + '/' + relpath)
|
|
||||||
|
|
||||||
|
|
||||||
class SaveFileView(ThinkMixin, generic.UpdateView):
|
class SaveFileView(ThinkMixin, generic.UpdateView):
|
||||||
|
@ -211,7 +191,6 @@ class SaveFileView(ThinkMixin, generic.UpdateView):
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
return self.object.get_absolute_url()+'?path='+str(self.path)
|
return self.object.get_absolute_url()+'?path='+str(self.path)
|
||||||
|
|
||||||
|
|
||||||
class RenameFileView(ThinkMixin, generic.UpdateView):
|
class RenameFileView(ThinkMixin, generic.UpdateView):
|
||||||
form_class = forms.RenameFileForm
|
form_class = forms.RenameFileForm
|
||||||
template_name = 'thinks/rename_file.html'
|
template_name = 'thinks/rename_file.html'
|
||||||
|
@ -224,7 +203,6 @@ class RenameFileView(ThinkMixin, generic.UpdateView):
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
return self.object.get_absolute_url()+'?path='+str(self.path)
|
return self.object.get_absolute_url()+'?path='+str(self.path)
|
||||||
|
|
||||||
|
|
||||||
class DeleteFileView(ThinkMixin, generic.UpdateView):
|
class DeleteFileView(ThinkMixin, generic.UpdateView):
|
||||||
form_class = forms.DeleteFileForm
|
form_class = forms.DeleteFileForm
|
||||||
template_name = 'thinks/delete_file.html'
|
template_name = 'thinks/delete_file.html'
|
||||||
|
@ -236,7 +214,6 @@ class DeleteFileView(ThinkMixin, generic.UpdateView):
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
return self.object.get_absolute_url()+'?path='+str(self.path.parent)
|
return self.object.get_absolute_url()+'?path='+str(self.path.parent)
|
||||||
|
|
||||||
|
|
||||||
class RunCommandView(ThinkMixin, generic.UpdateView):
|
class RunCommandView(ThinkMixin, generic.UpdateView):
|
||||||
form_class = forms.RunCommandForm
|
form_class = forms.RunCommandForm
|
||||||
|
|
||||||
|
@ -251,14 +228,6 @@ class RunCommandView(ThinkMixin, generic.UpdateView):
|
||||||
)
|
)
|
||||||
return JsonResponse({'stdout': res.stdout, 'stderr': res.stderr})
|
return JsonResponse({'stdout': res.stdout, 'stderr': res.stderr})
|
||||||
|
|
||||||
|
|
||||||
class UploadFileView(ThinkMixin, generic.UpdateView):
|
|
||||||
form_class = forms.UploadFileForm
|
|
||||||
|
|
||||||
def get_success_url(self):
|
|
||||||
return self.object.get_absolute_url()
|
|
||||||
|
|
||||||
|
|
||||||
class LogView(ThinkMixin, generic.DetailView):
|
class LogView(ThinkMixin, generic.DetailView):
|
||||||
template_name = 'thinks/think.html'
|
template_name = 'thinks/think.html'
|
||||||
|
|
||||||
|
@ -267,13 +236,11 @@ class LogView(ThinkMixin, generic.DetailView):
|
||||||
|
|
||||||
return HttpResponse(think.get_log(), content_type='text/plain; charset=utf-8')
|
return HttpResponse(think.get_log(), content_type='text/plain; charset=utf-8')
|
||||||
|
|
||||||
|
|
||||||
class JJStatusView(ThinkMixin, generic.detail.DetailView):
|
class JJStatusView(ThinkMixin, generic.detail.DetailView):
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
status = self.get_object().jj_controller.status()
|
status = self.get_object().jj_controller.status()
|
||||||
return JsonResponse({'status': status})
|
return JsonResponse({'status': status})
|
||||||
|
|
||||||
|
|
||||||
class JJCommitView(ThinkMixin, generic.UpdateView):
|
class JJCommitView(ThinkMixin, generic.UpdateView):
|
||||||
form_class = forms.GitCommitForm
|
form_class = forms.GitCommitForm
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue