소스 검색

Сделал "файлы" на странице проекта

Andrei 2 년 전
부모
커밋
3a7b651960
8개의 변경된 파일174개의 추가작업 그리고 11개의 파일을 삭제
  1. 6 1
      forms/project.py
  2. 30 1
      functions.py
  3. 15 4
      main.py
  4. 63 3
      static/css/project.css
  5. 7 1
      static/js/project.js
  6. 1 1
      templates/answer.html
  7. 47 0
      templates/project.html
  8. 5 0
      tets.py

+ 6 - 1
forms/project.py

@@ -1,5 +1,5 @@
 from flask_wtf import FlaskForm
-from wtforms import StringField, SubmitField, TextAreaField, FileField
+from wtforms import StringField, SubmitField, TextAreaField, FileField, MultipleFileField
 from wtforms.validators import DataRequired
 
 
@@ -10,3 +10,8 @@ class ProjectForm(FlaskForm):
     submit = SubmitField('Создать')
     del_photo = SubmitField('Удалить фотографию')
     save = SubmitField('Сохранить')
+
+
+class AddFileProject(FlaskForm):
+    file = MultipleFileField()
+    submit = SubmitField('Сохранить')

+ 30 - 1
functions.py

@@ -6,7 +6,6 @@ from email.message import EmailMessage
 from data.roles import Roles
 from data.users import User
 from data.staff_projects import StaffProjects
-from data.answer import Answer
 from data.files import Files
 from data import db_session
 import uuid
@@ -153,3 +152,33 @@ def find_files_answer(file_id):
     file = data_session.query(Files).filter(Files.id == file_id).first()
     return {'id': file.id, 'path': file.path, 'user': file.user, 'up_date': file.up_date,
             'current_path': file.path[str(file.path).find('all_projects') + 13:].split('/')}
+
+
+def file_tree(path):
+    tree = []
+    data_session = db_session.create_session()
+    h = 1
+    for i in os.listdir(path):
+        if os.path.isfile(f'{path}/{i}'):
+            file = data_session.query(Files).filter(Files.path == f'{path}/{i}').first()
+            tree.append(
+                {
+                    'path': f'{path}/{i}',
+                    'type': 'file',
+                    'object': file if file else None,
+                    'current_path': f'{path}/{i}'[str(file.path).find('all_projects') + 13:].split('/')
+                }
+            )
+        else:
+            tree.append(
+                {
+                    'id': h,
+                    'name': i,
+                    'path': f'{path}/{i}',
+                    'type': 'folder',
+                    'tree': file_tree(f'{path}/{i}')
+                }
+            )
+            h += 1
+    data_session.close()
+    return tree

+ 15 - 4
main.py

@@ -12,12 +12,12 @@ from sqlalchemy import or_
 from json import loads
 
 from functions import check_password, mail, init_db_default, get_projects_data, get_user_data, save_project_logo, \
-    overdue_quest_project, save_proof_quest, find_files_answer
+    overdue_quest_project, save_proof_quest, find_files_answer, file_tree
 from forms.edit_profile import EditProfileForm
 from forms.login import LoginForm
 from forms.find_project import FindProjectForm
 from forms.register import RegisterForm
-from forms.project import ProjectForm
+from forms.project import ProjectForm, AddFileProject
 from forms.recovery import RecoveryForm, NewPasswordForm
 from forms.conf_delete_project import DeleteProjectForm
 from forms.task import NewTask, AnswerTask
@@ -55,6 +55,7 @@ def base():
 @app.route('/project/<int:id_project>/file/<int:id_file>/delete')
 def delete_file(id_project, id_file):
     if current_user.is_authenticated:
+        from_path = request.args.get('from') if request.args.get('from') else ''
         data_session = db_session.create_session()
         current_project = data_session.query(Projects).filter(Projects.id == id_project).first()
         current_file = data_session.query(Files).filter(Files.id == id_file).first()
@@ -69,6 +70,8 @@ def delete_file(id_project, id_file):
                     for i in current_proof:
                         data_session.delete(i)
                     data_session.commit()
+                    if from_path == 'project':
+                        return redirect(f'/project/{current_project.id}')
                     return redirect(f'/project/{current_project.id}/quest/{quest[0]}')
                 data_session.commit()
                 return redirect(f'/project/{current_project.id}')
@@ -244,7 +247,7 @@ def edit_project(id_project):
         return redirect('/login')
 
 
-@app.route('/project/<int:id_project>')
+@app.route('/project/<int:id_project>', methods=['POST', 'GET'])
 def project(id_project):
     if current_user.is_authenticated:
         data_session = db_session.create_session()
@@ -262,11 +265,19 @@ def project(id_project):
                         filter(lambda x: x.deadline is None, quests)) + list(
                         filter(lambda x: x.realized == 1, quests_sort))
                     quests = list(map(lambda x: overdue_quest_project(x), quests))
+                files_list = file_tree(f'static/app_files/all_projects/{current_project.id}')
+                form_file = AddFileProject()
+                if form_file.validate_on_submit():
+                    if form_file.file.data[0].filename:
+                        files = list(
+                            map(lambda x: save_proof_quest(current_project, x, current_user.id), form_file.file.data))
                 return render_template('project.html',
                                        project=current_project,
                                        title=current_project.name,
                                        staff=staff,
-                                       quests=quests)
+                                       quests=quests,
+                                       file_tree=files_list,
+                                       form_file=form_file)
             else:
                 abort(403)
         else:

+ 63 - 3
static/css/project.css

@@ -83,6 +83,7 @@
     margin-top: 10px;
     overflow-x: auto;
     color: #000000 !important;
+    font-size: 1.5vw;
 }
 .link_to_user {
     width: 26vw;
@@ -122,7 +123,7 @@
     flex-direction: column;
     align-items: center;
 }
-.task_block {
+.task_block, .list_files_block {
     background-color: #EDCBB0;
     width: 95%;
     height: 25vw;
@@ -201,8 +202,8 @@
 }
 .deadline_block {
     border-radius: 5vw !important;
-    width: 15vw;
-    height: 70%;
+    width: 15vw !important;
+    height: 3vw !important;
     margin-top: 2%;
     font-size: 1vw;
     display: flex;
@@ -306,4 +307,63 @@
     display: flex;
     align-items: center;
     justify-content: center;
+}
+.files_block {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    width: 95%;
+    height: 50vw;
+}
+.list_files {
+    margin: 2vw;
+}
+.files_title {
+    text-align: center;
+    color: #000000;
+    font-size: 4vw;
+}
+.file {
+    width: 98%;
+    display: flex;
+    background-color: #9E795A;
+    margin: 0.5vw;
+    align-items: center;
+    justify-content: space-between;
+    flex-direction: row;
+    height: 4.5vw;
+    border-radius: 2vw;
+}
+.file_head {
+    width: 30vw;
+    margin-left: 1vw;
+    height: 4vw;
+    background-color: #9E795A !important;
+    overflow-y: hidden;
+    overflow-x: auto;
+}
+.file_head_path, .file_path {
+    font-size: 1.5vw;
+    color: #ffffff !important;
+    font-weight: bold;
+    height: 3vw;
+    display: flex;
+    align-items: flex-start;
+    background-color: #9E795A !important;
+}
+.file_buttons {
+    margin-right: 2vw; 
+}
+.file_delete, .file_download, .upload_button {
+    border-radius: 1vw !important;
+    margin: 1vw;
+    width: 8vw;
+    height: 3vw;
+}
+.file_delete {
+    background-color: hsla(0, 100%, 62%, 0.785) !important;
+    border-color: hsla(0, 100%, 62%, 0.785) !important;
+}
+.button_text {
+    font-size: 1.3vw;
 }

+ 7 - 1
static/js/project.js

@@ -5,4 +5,10 @@ quest_solve_link_id = document.getElementById("quest_solve_link_id");
 
 edit_button.href = String(window.location.href) + '/edit';
 new_task_link.href = String(window.location.href) + '/quest/new';
-quest_solve_link.href = String(window.location.href) + '/quest/' + quest_solve_link_id.className;
+
+function push_file()
+{
+    document.getElementById('selectedFile').click();
+    document.getElementById('upload_button').style = 'display: block;';
+    document.getElementById('select_file_button').style = 'display: none;';
+}

+ 1 - 1
templates/answer.html

@@ -33,7 +33,7 @@
                         </div>
                         <div class="file_buttons">
                             <div class="btn-group file_buttons_groud">
-                                {% if current_user.id == project.creator or task.creator == current_user.id or file.user == current_user.id %}
+                                {% if current_user.id == project.creator or task.creator == current_user.id or file['user'] == current_user.id %}
                                 <a href="../file/{{ file.id }}/delete" class="btn btn-primary file_delete"><p class="button_text">Удалить</p></a>
                                 {% endif %}
                                 <a href="../../../{{ file['path'] }}" download="" class="btn btn-primary file_download"><p class="button_text">Скачать</p></a>

+ 47 - 0
templates/project.html

@@ -126,7 +126,54 @@
         </div>
     </div>
     <div class="files_block">
+        <div class="head_files">
+            <h2 class="files_title">Файлы</h2>
+            <form action="" method="post" class="file_form" id="file_form" enctype="multipart/form-data">
+                {{ form_file.hidden_tag() }}
+                <div class="form_data bottom_data">
+                    {{ form_file.file(class="input_data", id="selectedFile", type="file", style="display: none;") }}
+                    {% for error in form_file.file.errors %}
+                    <div class="alert alert-danger" role="alert">{{ error }}</div>
+                    {% endfor %}
+                </div>
+                {{ form_file.submit(type="submit", id="upload_button", class="btn btn-success upload_button",
+                style="display: none;") }}
+                <button type="button" class="upload_button btn btn-primary" id="select_file_button"
+                        onclick="push_file()">Добавить
+                </button>
+            </form>
+        </div>
+        <div class="list_files_block">
+            <div class="list_files">
+                {% for item in file_tree %}
+                {% if item['type'] == 'file' %}
+                <div class="file">
+                    <div class="file_head">
+                        <nav class="file_head_group" style="--bs-breadcrumb-divider: '>';" aria-label="breadcrumb">
+                            <ol class="breadcrumb file_head_path">
+                                {% for path in item['current_path'] %}
+                                <li class="breadcrumb-item active file_path" aria-current="page">{{ path }}</li>
+                                {% endfor %}
+                            </ol>
+                        </nav>
+                    </div>
+                    <div class="file_buttons">
+                        <div class="btn-group file_buttons_groud">
+                            {% if current_user.id == project.creator or item['object'].user == current_user.id %}
+                            <a href="../project/{{ project.id }}/file/{{ item['object'].id }}/delete?from=project"
+                               class="btn btn-primary file_delete"><p class="button_text">Удалить</p></a>
+                            {% endif %}
+                            <a href="../../../{{ item['path'] }}" download="" class="btn btn-primary file_download"><p
+                                    class="button_text">Скачать</p></a>
+                        </div>
+                    </div>
+                </div>
+                {% elif item['type'] == 'folder' %}
 
+                {% endif %}
+                {% endfor %}
+            </div>
+        </div>
     </div>
 </div>
 <script type="text/javascript" src="../static/js/project.js"></script>

+ 5 - 0
tets.py

@@ -0,0 +1,5 @@
+import os
+
+path = os.listdir('.')
+print(path)
+print(os.path.isdir(path[6]))