zhongrj
2025-11-25 b89962006164a462404b79a738bee8cbb6d7fe7e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import importlib
import requests
import os
from os import path
 
from app import models, pending_actions
from app.plugins.views import TaskView
from app.plugins.worker import run_function_async
from app.plugins import get_current_plugin
 
from worker.celery import app
from rest_framework.response import Response
from rest_framework import status
 
from .platform_helper import get_all_platforms, get_platform_by_name
 
class ImportFolderTaskView(TaskView):
    def post(self, request, project_pk=None, pk=None):
        task = self.get_and_check_task(request, pk)
        
        # Read form data
        folder_url = request.data.get('selectedFolderUrl', None)
        platform_name = request.data.get('platform', None)
        
        # Make sure both values are set
        if folder_url == None or platform_name == None:
            return Response({'error': 'Folder URL and platform name must be set.'}, status=status.HTTP_400_BAD_REQUEST)
        
        # Fetch the platform by name    
        platform = get_platform_by_name(platform_name)
        
        # Make sure that the platform actually exists
        if platform == None:
            return Response({'error': 'Failed to find a platform with the name \'{}\''.format(platform_name)}, status=status.HTTP_400_BAD_REQUEST)
        
        # Verify that the folder url is valid    
        if platform.verify_folder_url(folder_url) == None:
            return Response({'error': 'Invalid URL'}, status=status.HTTP_400_BAD_REQUEST)
        
        # Get the files from the folder
        files = platform.import_from_folder(folder_url)
        
        # Update the task with the new information
        task.console += "Importing {} images...\n".format(len(files))
        task.images_count = len(files)
        task.pending_action = pending_actions.IMPORT
        task.save()
        
        # Associate the folder url with the project and task
        combined_id = "{}_{}".format(project_pk, pk)
        get_current_plugin().get_global_data_store().set_string(combined_id, folder_url)
 
        # Start importing the files in the background
        serialized = [file.serialize() for file in files]
        run_function_async(import_files, task.id, serialized)
 
        return Response({}, status=status.HTTP_200_OK)
 
class CheckUrlTaskView(TaskView):
    def get(self, request, project_pk=None, pk=None):
 
        # Assert that task exists
        self.get_and_check_task(request, pk)
 
        # Check if there is an imported url associated with the project and task
        combined_id = "{}_{}".format(project_pk, pk)
        folder_url = get_current_plugin().get_global_data_store().get_string(combined_id, default = None)
 
        if folder_url == None:
            return Response({}, status=status.HTTP_200_OK)
        else:
            return Response({'folder_url': folder_url}, status=status.HTTP_200_OK)
 
class PlatformsVerifyTaskView(TaskView):
    def get(self, request, platform_name):
        # Read the form data
        folder_url = request.GET.get('folderUrl', None)
        
        # Fetch the platform by name
        platform = get_platform_by_name(platform_name)
        
        # Make sure that the platform actually exists
        if platform == None:
            return Response({'error': 'Failed to find a platform with the name \'{}\''.format(platform_name)}, status=status.HTTP_400_BAD_REQUEST)
        
        # Verify that the folder url is valid    
        folder = platform.verify_folder_url(folder_url)
        if folder == None:
            return Response({'error': 'Invalid URL'}, status=status.HTTP_400_BAD_REQUEST)
        
        # Return the folder
        return Response({'folder': folder.serialize()}, status=status.HTTP_200_OK)
 
 
class PlatformsTaskView(TaskView):
    def get(self, request):
        # Fetch and return all platforms
        platforms = get_all_platforms()
        return Response({'platforms': [platform.serialize(user = request.user) for platform in platforms]}, status=status.HTTP_200_OK)
 
 
def import_files(task_id, files):
    import requests
    from app import models
    from app.plugins import logger
    from app.security import path_traversal_check
 
    def download_file(task, file):
        path = path_traversal_check(task.task_path(file['name']), task.task_path())
        download_stream = requests.get(file['url'], stream=True, timeout=60)
 
        with open(path, 'wb') as fd:
            for chunk in download_stream.iter_content(4096):
                fd.write(chunk)
        
    logger.info("Will import {} files".format(len(files)))
    task = models.Task.objects.get(pk=task_id)
    task.create_task_directories()
    task.save()
    
    try:
        downloaded_total = 0
        for file in files: 
            download_file(task, file)
            task.check_if_canceled()
            models.Task.objects.filter(pk=task.id).update(upload_progress=(float(downloaded_total) / float(len(files))))
            downloaded_total += 1
 
    except (requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
        raise NodeServerError(e)
 
    task.refresh_from_db()
    task.pending_action = None
    task.processing_time = 0
    task.partial = False
    task.images_count = len(task.scan_images())
    task.save()