Coverage for src/django_resume/plugins/identity.py: 55%
75 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-10-11 10:47 +0200
« prev ^ index » next coverage.py v7.6.1, created at 2024-10-11 10:47 +0200
1from django import forms
2from django.core.files.base import ContentFile
3from django.core.files.storage import default_storage
4from django.core.files.uploadedfile import InMemoryUploadedFile
5from django.forms.widgets import ClearableFileInput
6from django.http import HttpRequest
8from .base import SimplePlugin, SimpleTemplates, ContextDict
11class CustomFileObject:
12 def __init__(self, filename):
13 self.name = filename
14 self.url = default_storage.url(filename)
16 def __str__(self):
17 return self.name
20class CustomClearableFileInput(ClearableFileInput):
21 template_name = "custom_clearable_file_input.html"
23 def get_context(self, name, value, attrs):
24 value = CustomFileObject(value)
25 context = super().get_context(name, value, attrs)
26 context["widget"]["is_initial"] = self.is_initial(value)
27 return context
30class IdentityForm(forms.Form):
31 template_name = "django_resume/identity/plain/form_as_div.html"
32 name = forms.CharField(label="Your name", max_length=100, initial="Your name")
33 pronouns = forms.CharField(
34 label="Pronouns", max_length=100, initial="your/pronouns"
35 )
36 tagline = forms.CharField(
37 label="Tagline", max_length=512, initial="Some tagline text."
38 )
39 location_name = forms.CharField(
40 label="Location", max_length=100, initial="City, Country, Timezone"
41 )
42 location_url = forms.URLField(
43 label="Location url",
44 max_length=100,
45 initial="https://maps.app.goo.gl/TkuHEzeGpr7u2aCD7",
46 assume_scheme="https",
47 )
48 avatar_img = forms.FileField(
49 label="Profile Image",
50 max_length=100,
51 required=False,
52 widget=CustomClearableFileInput,
53 )
54 avatar_alt = forms.CharField(
55 label="Profile photo alt text",
56 max_length=100,
57 initial="Profile photo",
58 required=False,
59 )
60 clear_avatar = forms.BooleanField(
61 widget=forms.CheckboxInput, initial=False, required=False
62 )
63 email = forms.EmailField(
64 label="Email address",
65 max_length=100,
66 initial="foobar@example.com",
67 )
68 phone = forms.CharField(
69 label="Phone number",
70 max_length=100,
71 initial="+1 555 555 5555",
72 )
73 github = forms.URLField(
74 label="GitHub url",
75 max_length=100,
76 initial="https://github.com/foobar/",
77 assume_scheme="https",
78 )
79 linkedin = forms.URLField(
80 label="LinkedIn profile url",
81 max_length=100,
82 initial="https://linkedin.com/foobar/",
83 assume_scheme="https",
84 )
85 mastodon = forms.URLField(
86 label="Mastodon url",
87 max_length=100,
88 initial="https://fosstodon.org/@foobar",
89 assume_scheme="https",
90 )
92 def __init__(self, *args, **kwargs):
93 super().__init__(*args, **kwargs)
94 initial_avatar_img_filename = self.initial.get("avatar_img")
95 print("initial avatar img: ", initial_avatar_img_filename)
96 if initial_avatar_img_filename is not None: 96 ↛ 97line 96 didn't jump to line 97 because the condition on line 96 was never true
97 self.fields["avatar_img"].initial = CustomFileObject(
98 initial_avatar_img_filename
99 )
100 print("initial avatar img: ", self.fields["avatar_img"].initial)
102 @property
103 def avatar_img_url(self):
104 return default_storage.url(self.initial.get("avatar_img", ""))
106 def clean(self):
107 # super ugly - FIXME
108 cleaned_data = super().clean()
109 avatar_img = cleaned_data.get("avatar_img")
110 clear_avatar = cleaned_data.get("clear_avatar")
111 print("cleaned_data: ", cleaned_data)
113 avatar_handled = False
114 just_clear_the_avatar = clear_avatar and not hasattr(
115 avatar_img, "temporary_file_path"
116 )
117 if just_clear_the_avatar:
118 cleaned_data["avatar_img"] = None
119 avatar_handled = True
121 set_new_avatar_image = (
122 isinstance(avatar_img, InMemoryUploadedFile) and not avatar_handled
123 )
124 if set_new_avatar_image:
125 if avatar_img.size > 2 * 1024 * 1024:
126 raise forms.ValidationError("Image file too large ( > 2mb )")
127 cleaned_data["avatar_img"] = default_storage.save(
128 f"uploads/{avatar_img.name}", ContentFile(avatar_img.read())
129 )
130 avatar_handled = True
132 keep_current_avatar = (
133 not clear_avatar and isinstance(avatar_img, str) and not avatar_handled
134 )
135 if keep_current_avatar:
136 cleaned_data["avatar_img"] = avatar_img
138 del cleaned_data["clear_avatar"] # reset the clear_avatar field
139 return cleaned_data
142class IdentityPlugin(SimplePlugin):
143 name: str = "identity"
144 verbose_name: str = "Identity Information"
145 templates = SimpleTemplates(
146 main="django_resume/identity/plain/content.html",
147 form="django_resume/identity/plain/form.html",
148 )
149 admin_form_class = inline_form_class = IdentityForm
151 def get_context(
152 self,
153 _request: HttpRequest,
154 plugin_data: dict,
155 resume_pk: int,
156 *,
157 context: ContextDict,
158 edit: bool = False,
159 ) -> ContextDict:
160 context = super().get_context(
161 _request, plugin_data, resume_pk, context=context, edit=edit
162 )
163 context["avatar_img_url"] = default_storage.url(
164 plugin_data.get("avatar_img", "")
165 )
166 return context