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