Passed
Push — master ( f7c14f...06873a )
by Swen
02:26
created

LocalizedFieldFile   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 34
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 3
Bugs 0 Features 1
Metric Value
wmc 7
c 3
b 0
f 1
dl 0
loc 34
rs 10
ccs 23
cts 23
cp 1

3 Methods

Rating   Name   Duplication   Size   Complexity  
A delete() 0 15 4
A save() 0 8 2
A __init__() 0 3 1
1 1
import datetime
2 1
import posixpath
3
4 1
from django.core.files import File
0 ignored issues
show
Configuration introduced by
The import django.core.files could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
5 1
from django.db.models.fields.files import FieldFile
0 ignored issues
show
Configuration introduced by
The import django.db.models.fields.files could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
6 1
from django.utils import six
0 ignored issues
show
Configuration introduced by
The import django.utils could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
7 1
from django.core.files.storage import default_storage
0 ignored issues
show
Configuration introduced by
The import django.core.files.storage could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
8 1
from django.utils.encoding import force_str, force_text
0 ignored issues
show
Configuration introduced by
The import django.utils.encoding could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
9
10 1
from localized_fields.fields import LocalizedField
11 1
from localized_fields.fields.field import LocalizedValueDescriptor
12 1
from localized_fields.value import LocalizedValue
13
14 1
from ..value import LocalizedFileValue
15 1
from ..forms import LocalizedFileFieldForm
16
17
18 1
class LocalizedFieldFile(FieldFile):
19
20 1
    def __init__(self, instance, field, name, lang):
21 1
        super().__init__(instance, field, name)
22 1
        self.lang = lang
23
24 1
    def save(self, name, content, save=True):
25 1
        name = self.field.generate_filename(self.instance, name, self.lang)
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFieldFile does not seem to have a member named field.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
Bug introduced by
The Instance of LocalizedFieldFile does not seem to have a member named instance.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
26 1
        self.name = self.storage.save(name, content,
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFieldFile does not seem to have a member named storage.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
Coding Style introduced by
The attribute name was defined outside __init__.

It is generally a good practice to initialize all attributes to default values in the __init__ method:

class Foo:
    def __init__(self, x=None):
        self.x = x
Loading history...
27
                                      max_length=self.field.max_length)
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFieldFile does not seem to have a member named field.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
28 1
        self._committed = True
0 ignored issues
show
Coding Style introduced by
The attribute _committed was defined outside __init__.

It is generally a good practice to initialize all attributes to default values in the __init__ method:

class Foo:
    def __init__(self, x=None):
        self.x = x
Loading history...
29
30 1
        if save:
31 1
            self.instance.save()
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFieldFile does not seem to have a member named instance.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
32
33 1
    save.alters_data = True
34
35 1
    def delete(self, save=True):
36 1
        if not self:
37 1
            return
38
39 1
        if hasattr(self, '_file'):
40 1
            self.close()
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFieldFile does not seem to have a member named close.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
41 1
            del self.file
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFieldFile does not seem to have a member named file.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
42
43 1
        self.storage.delete(self.name)
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFieldFile does not seem to have a member named storage.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
44
45 1
        self.name = None
0 ignored issues
show
Coding Style introduced by
The attribute name was defined outside __init__.

It is generally a good practice to initialize all attributes to default values in the __init__ method:

class Foo:
    def __init__(self, x=None):
        self.x = x
Loading history...
46 1
        self._committed = False
0 ignored issues
show
Coding Style introduced by
The attribute _committed was defined outside __init__.

It is generally a good practice to initialize all attributes to default values in the __init__ method:

class Foo:
    def __init__(self, x=None):
        self.x = x
Loading history...
47
48 1
        if save:
49 1
            self.instance.save()
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFieldFile does not seem to have a member named instance.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
50
51 1
    delete.alters_data = True
52
53
54 1
class LocalizedFileValueDescriptor(LocalizedValueDescriptor):
55 1
    def __get__(self, instance, cls=None):
56 1
        value = super().__get__(instance, cls)
57 1
        for lang, file in value.__dict__.items():
58 1
            if isinstance(file, six.string_types) or file is None:
59 1
                file = self.field.value_class(instance, self.field, file, lang)
60 1
                value.set(lang, file)
61
62 1
            elif isinstance(file, File) and \
63
                    not isinstance(file, LocalizedFieldFile):
64 1
                file_copy = self.field.value_class(instance, self.field,
65
                                                   file.name, lang)
66 1
                file_copy.file = file
67 1
                file_copy._committed = False
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _committed was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
68 1
                value.set(lang, file_copy)
69
70 1
            elif isinstance(file, LocalizedFieldFile) and \
71
                    not hasattr(file, 'field'):
72 1
                file.instance = instance
73 1
                file.field = self.field
74 1
                file.storage = self.field.storage
75 1
                file.lang = lang
76
77
            # Make sure that the instance is correct.
78 1
            elif isinstance(file, LocalizedFieldFile) \
79
                    and instance is not file.instance:
80 1
                file.instance = instance
81 1
                file.lang = lang
82 1
        return value
83
84
85 1
class LocalizedFileField(LocalizedField):
86 1
    descriptor_class = LocalizedFileValueDescriptor
87 1
    attr_class = LocalizedFileValue
88 1
    value_class = LocalizedFieldFile
89
90 1
    def __init__(self, verbose_name=None, name=None, upload_to='', storage=None,
91
                 **kwargs):
92
93 1
        self.storage = storage or default_storage
94 1
        self.upload_to = upload_to
95
96 1
        super().__init__(verbose_name, name, **kwargs)
97
98 1
    def deconstruct(self):
99 1
        name, path, args, kwargs = super().deconstruct()
100 1
        kwargs['upload_to'] = self.upload_to
101 1
        if self.storage is not default_storage:
102 1
            kwargs['storage'] = self.storage
103 1
        return name, path, args, kwargs
104
105 1
    def get_prep_value(self, value):
106
        """Returns field's value prepared for saving into a database."""
107
108 1
        if isinstance(value, LocalizedValue):
109 1
            prep_value = LocalizedValue()
110 1
            for k, v in value.__dict__.items():
111 1
                if v is None:
112 1
                    prep_value.set(k, '')
113
                else:
114
                    # Need to convert File objects provided via a form to
115
                    # unicode for database insertion
116 1
                    prep_value.set(k, six.text_type(v))
117 1
            return super().get_prep_value(prep_value)
118 1
        return super().get_prep_value(value)
119
120 1
    def pre_save(self, model_instance, add):
0 ignored issues
show
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
121
        """Returns field's value just before saving."""
122 1
        value = super().pre_save(model_instance, add)
123 1
        if isinstance(value, LocalizedValue):
124 1
            for file in value.__dict__.values():
125 1
                if file and not file._committed:
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _committed was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
126 1
                    file.save(file.name, file, save=False)
127 1
        return value
128
129 1
    def generate_filename(self, instance, filename, lang):
130 1
        if callable(self.upload_to):
131 1
            filename = self.upload_to(instance, filename, lang)
132
        else:
133 1
            now = datetime.datetime.now()
134 1
            dirname = force_text(now.strftime(force_str(self.upload_to)))
135 1
            dirname = dirname.format(lang=lang)
136 1
            filename = posixpath.join(dirname, filename)
137 1
        return self.storage.generate_filename(filename)
138
139 1
    def save_form_data(self, instance, data):
140 1
        if isinstance(data, LocalizedValue):
141 1
            for k, v in data.__dict__.items():
142 1
                if v is not None and not v:
143 1
                    data.set(k, '')
144 1
            setattr(instance, self.name, data)
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFileField does not seem to have a member named name.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
145
146 1
    def formfield(self, **kwargs):
147 1
        defaults = {'form_class': LocalizedFileFieldForm}
148 1
        if 'initial' in kwargs:
149
            defaults['required'] = False
150 1
        defaults.update(kwargs)
151
        return super().formfield(**defaults)
0 ignored issues
show
Coding Style introduced by
Usage of * or ** arguments should usually be done with care.

Generally, there is nothing wrong with usage of * or ** arguments. For readability of the code base, we suggest to not over-use these language constructs though.

For more information, we can recommend this blog post from Ned Batchelder including its comments which also touches this aspect.

Loading history...
152