Completed
Push — file-actions ( 5064d9 )
by Felipe A.
26s
created

clipboard_paste()   F

Complexity

Conditions 10

Size

Total Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 32
rs 3.1304
cc 10

How to fix   Complexity   

Complexity

Complex classes like clipboard_paste() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
#!/usr/bin/env python
2
# -*- coding: UTF-8 -*-
3
4
import os
5
import os.path
6
import shutil
7
8
from flask import Blueprint, render_template, request, redirect, url_for
9
from werkzeug.exceptions import NotFound
10
11
from browsepy import get_cookie_browse_sorting, browse_sortkey_reverse
12
from browsepy.file import Node
13
from browsepy.compat import map
14
from browsepy.exceptions import OutsideDirectoryBase
15
16
from .clipboard import Clipboard
17
18
19
__basedir__ = os.path.dirname(os.path.abspath(__file__))
20
21
actions = Blueprint(
22
    'file_actions',
23
    __name__,
24
    url_prefix='/file-actions',
25
    template_folder=os.path.join(__basedir__, 'templates'),
26
    static_folder=os.path.join(__basedir__, 'static'),
27
    )
28
29
30
@actions.route('/create/directory', methods=('GET', 'POST'),
31
               defaults={'path': ''})
32
@actions.route('/create/directory/<path:path>', methods=('GET', 'POST'))
33
def create_directory(path):
34
    try:
35
        directory = Node.from_urlpath(path)
36
    except OutsideDirectoryBase:
37
        return NotFound()
38
39
    if not directory.is_directory or not directory.can_upload:
40
        return NotFound()
41
42
    if request.method == 'GET':
43
        return render_template('create_directory.html', file=directory)
44
45
    os.mkdir(os.path.join(directory.path, request.form['name']))
46
47
    return redirect(url_for('browse', path=directory.urlpath))
48
49
50
@actions.route('/clipboard', methods=('GET', 'POST'), defaults={'path': ''})
51
@actions.route('/clipboard/<path:path>', methods=('GET', 'POST'))
52
def clipboard(path):
53
    sort_property = get_cookie_browse_sorting(path, 'text')
54
    sort_fnc, sort_reverse = browse_sortkey_reverse(sort_property)
55
56
    try:
57
        directory = Node.from_urlpath(path)
58
    except OutsideDirectoryBase:
59
        return NotFound()
60
61
    if directory.is_excluded or not directory.is_directory:
62
        return NotFound()
63
64
    if request.method == 'POST':
65
        mode = 'cut' if request.form.get('mode-cut', None) else 'copy'
66
        response = redirect(url_for('browse', path=directory.urlpath))
67
        clipboard = Clipboard(request.form.getlist('path'), mode)
68
        clipboard.to_response(response)
69
        return response
70
71
    clipboard = Clipboard.from_request()
72
    return render_template(
73
        'clipboard.html',
74
        file=directory,
75
        clipboard=clipboard,
76
        sort_property=sort_property,
77
        sort_fnc=sort_fnc,
78
        sort_reverse=sort_reverse,
79
        )
80
81
82
@actions.route('/clipboard/paste', defaults={'path': ''})
83
@actions.route('/clipboard/paste/<path:path>')
84
def clipboard_paste(path):
85
    try:
86
        directory = Node.from_urlpath(path)
87
    except OutsideDirectoryBase:
88
        return NotFound()
89
90
    if (
91
      not directory.is_directory or
92
      directory.is_excluded or
93
      not directory.can_upload
94
      ):
95
        return NotFound()
96
97
    response = redirect(url_for('browse', path=directory.urlpath))
98
    clipboard = Clipboard.from_request()
99
    cut = clipboard.mode == 'cut'
100
101
    for node in map(Node.from_urlpath, clipboard):
102
        if not node.is_excluded:
103
            if not cut:
104
                if node.is_directory:
105
                    shutil.copytree(node.path, directory.path)
106
                else:
107
                    shutil.copy2(node.path, directory.path)
108
            elif node.parent.can_remove:
109
                shutil.move(node.path, directory.path)
110
111
    clipboard.clear()
112
    clipboard.to_response(response)
113
    return response
114
115
116
@actions.route('/clipboard/clear', defaults={'path': ''})
117
@actions.route('/clipboard/clear/<path:path>')
118
def clipboard_clear(path):
119
    response = redirect(url_for('browse', path=path))
120
    clipboard = Clipboard.from_request()
121
    clipboard.clear()
122
    clipboard.to_response(response)
123
    return response
124
125
126
def register_plugin(manager):
127
    '''
128
    Register blueprints and actions using given plugin manager.
129
130
    :param manager: plugin manager
131
    :type manager: browsepy.manager.PluginManager
132
    '''
133
    manager.register_blueprint(actions)
134
135
    # add style tag
136
    manager.register_widget(
137
        place='styles',
138
        type='stylesheet',
139
        endpoint='file_actions.static',
140
        filename='css/browse.css'
141
        )
142
143
    # register header button
144
    manager.register_widget(
145
        place='header',
146
        type='button',
147
        endpoint='file_actions.create_directory',
148
        text='Create directory',
149
        filter=lambda file: file.can_upload,
150
        )
151
    manager.register_widget(
152
        place='header',
153
        type='button',
154
        endpoint='file_actions.clipboard',
155
        text=lambda file: (
156
            '{} items selected'.format(Clipboard.count())
157
            if Clipboard.count() else
158
            'Selection...'
159
            ),
160
        )
161
    manager.register_widget(
162
        place='header',
163
        type='button',
164
        endpoint='file_actions.clipboard_paste',
165
        text='Paste here',
166
        filter=Clipboard.detect_target,
167
        )
168
    manager.register_widget(
169
        place='header',
170
        type='button',
171
        endpoint='file_actions.clipboard_clear',
172
        text='Clear',
173
        filter=Clipboard.detect,
174
        )
175