django-bom 1.237__py3-none-any.whl → 1.239__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bom/auth_backends.py +45 -0
- bom/models.py +8 -33
- bom/templates/bom/_subscription_panel.html +6 -0
- bom/templates/bom/bom-modal-add-users.html +49 -0
- bom/templates/bom/settings.html +9 -18
- bom/views/views.py +10 -4
- {django_bom-1.237.dist-info → django_bom-1.239.dist-info}/METADATA +1 -1
- {django_bom-1.237.dist-info → django_bom-1.239.dist-info}/RECORD +11 -8
- {django_bom-1.237.dist-info → django_bom-1.239.dist-info}/WHEEL +0 -0
- {django_bom-1.237.dist-info → django_bom-1.239.dist-info}/licenses/LICENSE +0 -0
- {django_bom-1.237.dist-info → django_bom-1.239.dist-info}/top_level.txt +0 -0
bom/auth_backends.py
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from . import constants
|
|
4
|
+
from .models import Organization
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class OrganizationPermissionBackend:
|
|
8
|
+
"""
|
|
9
|
+
Object-level permission backend for django-bom.
|
|
10
|
+
|
|
11
|
+
- Uses Django's has_perm(user, perm, obj) to evaluate permissions tied to an Organization.
|
|
12
|
+
- Superusers are granted all permissions.
|
|
13
|
+
- For `bom.manage_members`: User must be owner or admin within the organization.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def authenticate(self, request, **credentials): # pragma: no cover - not used for auth
|
|
17
|
+
return None
|
|
18
|
+
|
|
19
|
+
def has_perm(self, user_obj, perm: str, obj: Optional[object] = None):
|
|
20
|
+
# Only handle our specific object-level permission. Let other backends process others.
|
|
21
|
+
if not user_obj or not user_obj.is_authenticated:
|
|
22
|
+
return False
|
|
23
|
+
|
|
24
|
+
if user_obj.is_superuser:
|
|
25
|
+
return True
|
|
26
|
+
|
|
27
|
+
if perm != 'bom.manage_members':
|
|
28
|
+
return None
|
|
29
|
+
|
|
30
|
+
if obj is None or not isinstance(obj, Organization):
|
|
31
|
+
return False
|
|
32
|
+
|
|
33
|
+
profile = user_obj.bom_profile()
|
|
34
|
+
if not profile or profile.organization_id != obj.id:
|
|
35
|
+
return False
|
|
36
|
+
|
|
37
|
+
if obj.subscription != constants.SUBSCRIPTION_TYPE_PRO:
|
|
38
|
+
return False
|
|
39
|
+
|
|
40
|
+
is_owner = obj.owner_id == user_obj.id
|
|
41
|
+
is_admin = getattr(profile, 'role', None) == constants.ROLE_TYPE_ADMIN
|
|
42
|
+
if not (is_owner or is_admin):
|
|
43
|
+
return False
|
|
44
|
+
|
|
45
|
+
return True
|
bom/models.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from __future__ import unicode_literals
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from math import ceil
|
|
5
4
|
|
|
6
5
|
from django.conf import settings
|
|
7
6
|
from django.contrib.auth import get_user_model
|
|
@@ -9,45 +8,16 @@ from django.core.cache import cache
|
|
|
9
8
|
from django.core.validators import MaxValueValidator, MinValueValidator
|
|
10
9
|
from django.db import models
|
|
11
10
|
from django.utils import timezone
|
|
12
|
-
|
|
13
11
|
from djmoney.models.fields import CURRENCY_CHOICES, CurrencyField, MoneyField
|
|
12
|
+
from math import ceil
|
|
14
13
|
from social_django.models import UserSocialAuth
|
|
15
14
|
|
|
16
15
|
from .base_classes import AsDictModel
|
|
17
|
-
from .constants import
|
|
18
|
-
CONFIGURATION_TYPES,
|
|
19
|
-
CURRENT_UNITS,
|
|
20
|
-
DISTANCE_UNITS,
|
|
21
|
-
FREQUENCY_UNITS,
|
|
22
|
-
INTERFACE_TYPES,
|
|
23
|
-
MEMORY_UNITS,
|
|
24
|
-
NUMBER_CLASS_CODE_LEN_DEFAULT,
|
|
25
|
-
NUMBER_CLASS_CODE_LEN_MAX,
|
|
26
|
-
NUMBER_CLASS_CODE_LEN_MIN,
|
|
27
|
-
NUMBER_ITEM_LEN_DEFAULT,
|
|
28
|
-
NUMBER_ITEM_LEN_MAX,
|
|
29
|
-
NUMBER_ITEM_LEN_MIN,
|
|
30
|
-
NUMBER_SCHEME_INTELLIGENT,
|
|
31
|
-
NUMBER_SCHEME_SEMI_INTELLIGENT,
|
|
32
|
-
NUMBER_SCHEMES,
|
|
33
|
-
NUMBER_VARIATION_LEN_DEFAULT,
|
|
34
|
-
NUMBER_VARIATION_LEN_MAX,
|
|
35
|
-
NUMBER_VARIATION_LEN_MIN,
|
|
36
|
-
PACKAGE_TYPES,
|
|
37
|
-
POWER_UNITS,
|
|
38
|
-
ROLE_TYPES,
|
|
39
|
-
SUBSCRIPTION_TYPES,
|
|
40
|
-
TEMPERATURE_UNITS,
|
|
41
|
-
VALUE_UNITS,
|
|
42
|
-
VOLTAGE_UNITS,
|
|
43
|
-
WAVELENGTH_UNITS,
|
|
44
|
-
WEIGHT_UNITS,
|
|
45
|
-
)
|
|
16
|
+
from .constants import *
|
|
46
17
|
from .csv_headers import PartsListCSVHeaders, PartsListCSVHeadersSemiIntelligent
|
|
47
18
|
from .part_bom import PartBom, PartBomItem, PartIndentedBomItem
|
|
48
19
|
from .utils import increment_str, listify_string, prep_for_sorting_nicely, stringify_list, strip_trailing_zeros
|
|
49
|
-
from .validators import alphanumeric,
|
|
50
|
-
|
|
20
|
+
from .validators import alphanumeric, validate_pct
|
|
51
21
|
|
|
52
22
|
logger = logging.getLogger(__name__)
|
|
53
23
|
User = get_user_model()
|
|
@@ -75,6 +45,11 @@ class Organization(models.Model):
|
|
|
75
45
|
google_drive_parent = models.CharField(max_length=128, blank=True, default=None, null=True)
|
|
76
46
|
currency = CurrencyField(max_length=3, choices=CURRENCY_CHOICES, default='USD')
|
|
77
47
|
|
|
48
|
+
class Meta:
|
|
49
|
+
permissions = (
|
|
50
|
+
("manage_members", "Can manage organization members"),
|
|
51
|
+
)
|
|
52
|
+
|
|
78
53
|
def number_cs(self):
|
|
79
54
|
return "C" * self.number_class_code_len
|
|
80
55
|
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{# Placeholder for subscription/billing UI. Host applications (e.g., indabom) can override this template by providing their own `bom/_subscription_panel.html` earlier in the template search path. #}
|
|
2
|
+
<div class="row">
|
|
3
|
+
<div class="col">
|
|
4
|
+
<i>As a self-hosted django-bom app, you can upgrade any organization using the admin dashboard by finding your <b>Organization</b> and changing the <b>Subscription</b> property to <b>Pro</b>.</i>
|
|
5
|
+
</div>
|
|
6
|
+
</div>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{% load materializecss %}
|
|
2
|
+
{% load static %}
|
|
3
|
+
|
|
4
|
+
<a class="waves-effect waves-light btn btn-primary modal-trigger modal-{{ name }}"
|
|
5
|
+
href="#modal-{{ name }}">{{ modal_title }}</a>
|
|
6
|
+
|
|
7
|
+
<div id="modal-{{ name }}" class="modal left-align">
|
|
8
|
+
<form name="seller" action="{{ action }}" method="post" class="col s12" enctype="multipart/form-data">
|
|
9
|
+
<div class="modal-content">
|
|
10
|
+
<div class="row">
|
|
11
|
+
{% if modal_title %}<h2 class="light" style="margin-top: 0;">{{ modal_title }}</h2>{% endif %}
|
|
12
|
+
<div class="col s12">
|
|
13
|
+
{% if is_pro and user_can_manage_members %}
|
|
14
|
+
{% csrf_token %}
|
|
15
|
+
<p class="flow-text-small grey-text text-darken-2">To add a user, ensure they have already
|
|
16
|
+
created an IndaBOM account and are not currently part of another organization.
|
|
17
|
+
Then, enter their <b>username</b> (not email) and select their role below.</p>
|
|
18
|
+
{{ form|materializecss:'m6 s12' }}
|
|
19
|
+
{% elif is_pro and not user_can_manage_members %}
|
|
20
|
+
<p class="flow-text-small red-text text-darken-1">
|
|
21
|
+
<b>Access Restricted:</b> Please contact an organization administrator to add new members to
|
|
22
|
+
your team.
|
|
23
|
+
</p>
|
|
24
|
+
{% else %}
|
|
25
|
+
<p>Upgrade your organization subscription to professional to manage members.</p>
|
|
26
|
+
{% endif %}
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
<div class="modal-footer">
|
|
31
|
+
<a href="#!" class="modal-close waves-effect waves-green btn-flat">Cancel</a>
|
|
32
|
+
{% if is_pro and user_can_manage_members %}
|
|
33
|
+
<button class="waves-effect waves-light btn btn-primary" type="submit" name="{{ name }}">Submit</button>
|
|
34
|
+
{% elif is_pro and not user_can_manage_members %}
|
|
35
|
+
<a href="#!" class="modal-close waves-effect green lighten-1 waves-green btn-flat">Ok</a>
|
|
36
|
+
{% else %}
|
|
37
|
+
<a href="#!" class="modal-close waves-effect green lighten-1 waves-green btn-flat">Ok</a>
|
|
38
|
+
{% endif %}
|
|
39
|
+
</div>
|
|
40
|
+
</form>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
{% block script %}
|
|
44
|
+
<script>
|
|
45
|
+
$(document).ready(function () {
|
|
46
|
+
$('.modal').modal();
|
|
47
|
+
});
|
|
48
|
+
</script>
|
|
49
|
+
{% endblock %}
|
bom/templates/bom/settings.html
CHANGED
|
@@ -186,6 +186,7 @@
|
|
|
186
186
|
<div id="organization" class="col s12">
|
|
187
187
|
{% if user.bom_profile.role == 'A' %}
|
|
188
188
|
<h3>Organization</h3>
|
|
189
|
+
{% include 'bom/_subscription_panel.html' %}
|
|
189
190
|
<div class="row">
|
|
190
191
|
<div class="col s12">
|
|
191
192
|
<form name="seller" action="{% url 'bom:settings' tab_anchor=ORGANIZATION_TAB %}" method="post" class="col s12" enctype="multipart/form-data">
|
|
@@ -207,7 +208,6 @@
|
|
|
207
208
|
<div class="row">
|
|
208
209
|
<div class="col s12">
|
|
209
210
|
<h3>Users</h3>
|
|
210
|
-
{% if users_in_organization.count > 0 %}
|
|
211
211
|
<form name="seller" action="{% url 'bom:settings' tab_anchor=ORGANIZATION_TAB %}" method="post" class="col s12" enctype="multipart/form-data">
|
|
212
212
|
{% csrf_token %}
|
|
213
213
|
<table>
|
|
@@ -237,6 +237,13 @@
|
|
|
237
237
|
class="material-icons left">edit</i>Edit</a>
|
|
238
238
|
</td>
|
|
239
239
|
</tr>
|
|
240
|
+
{% empty %}
|
|
241
|
+
<tr>
|
|
242
|
+
<td colspan="5" style="font-style: italic;">There are no additional
|
|
243
|
+
users in this
|
|
244
|
+
organization.
|
|
245
|
+
</td>
|
|
246
|
+
</tr>
|
|
240
247
|
{% endfor %}
|
|
241
248
|
</tbody>
|
|
242
249
|
</table>
|
|
@@ -247,26 +254,10 @@
|
|
|
247
254
|
</button>
|
|
248
255
|
</div>
|
|
249
256
|
<div class="col s6 right-align">
|
|
250
|
-
{% include 'bom/bom-
|
|
257
|
+
{% include 'bom/bom-modal-add-users.html' with modal_title='Add User' form=user_add_form action=user_add_form_action name='submit-add-user' %}
|
|
251
258
|
</div>
|
|
252
259
|
</div>
|
|
253
260
|
</form>
|
|
254
|
-
{% else %}
|
|
255
|
-
<div class="row" style="padding-left: .75rem;">
|
|
256
|
-
<div class="col s12">
|
|
257
|
-
<p>There are no additional users in this organization: {{ organization }}.</p>
|
|
258
|
-
{% if organization.subscription == 'F' %}
|
|
259
|
-
{% include 'bom/bom-form-modal.html' with modal_title='Add User' name='submit-add-user-free' modal_description='Adding users to your organization is a paid feature, but is free for a limited time while we are still developing the tool. Contact <a href="mailto:info@indabom.com">info@indabom.com</a> if you are interested.' %}
|
|
260
|
-
{% else %}
|
|
261
|
-
{% if organization.subscription_quantity == 0 or users_in_organization.count < organization.subscription_quantity %}
|
|
262
|
-
{% include 'bom/bom-form-modal.html' with modal_title='Add User' form=user_add_form action=user_add_form_action name='submit-add-user' modal_description='Add a user to your organization.' %}
|
|
263
|
-
{% else %}
|
|
264
|
-
<p>You've added the maximum number of users to this organization. Update your subscription to add more.</p>
|
|
265
|
-
{% endif %}
|
|
266
|
-
{% endif %}
|
|
267
|
-
</div>
|
|
268
|
-
</div>
|
|
269
|
-
{% endif %}
|
|
270
261
|
</div>
|
|
271
262
|
</div>
|
|
272
263
|
<div class="row">
|
bom/views/views.py
CHANGED
|
@@ -20,7 +20,6 @@ from django.urls import reverse
|
|
|
20
20
|
from django.utils.encoding import smart_str
|
|
21
21
|
from django.utils.text import smart_split
|
|
22
22
|
from django.views.generic.base import TemplateView
|
|
23
|
-
|
|
24
23
|
from social_django.models import UserSocialAuth
|
|
25
24
|
|
|
26
25
|
import bom.constants as constants
|
|
@@ -74,7 +73,6 @@ from bom.models import (
|
|
|
74
73
|
)
|
|
75
74
|
from bom.utils import check_references_for_duplicates, listify_string, prep_for_sorting_nicely
|
|
76
75
|
|
|
77
|
-
|
|
78
76
|
logger = logging.getLogger(__name__)
|
|
79
77
|
BOM_LOGIN_URL = getattr(settings, "BOM_LOGIN_URL", None) or settings.LOGIN_URL
|
|
80
78
|
|
|
@@ -361,6 +359,12 @@ def bom_settings(request, tab_anchor=None):
|
|
|
361
359
|
users_in_organization = User.objects.filter(
|
|
362
360
|
id__in=UserMeta.objects.filter(organization=organization).values_list('user', flat=True)).exclude(id__in=[organization.owner.id]).order_by(
|
|
363
361
|
'first_name', 'last_name', 'email')
|
|
362
|
+
users_in_organization_count = users_in_organization.count()
|
|
363
|
+
has_member_capacity = users_in_organization_count < organization.subscription_quantity
|
|
364
|
+
# Seats available for adding new members (never negative)
|
|
365
|
+
seats_available = max(organization.subscription_quantity - users_in_organization_count, 0)
|
|
366
|
+
is_pro = organization.subscription == constants.SUBSCRIPTION_TYPE_PRO
|
|
367
|
+
user_can_manage_members = request.user.has_perm('bom.manage_members', organization)
|
|
364
368
|
google_authentication = UserSocialAuth.objects.filter(user=user).first()
|
|
365
369
|
|
|
366
370
|
organization_parts_count = Part.objects.filter(organization=organization).count()
|
|
@@ -386,8 +390,10 @@ def bom_settings(request, tab_anchor=None):
|
|
|
386
390
|
|
|
387
391
|
elif 'submit-add-user' in request.POST:
|
|
388
392
|
tab_anchor = ORGANIZATION_TAB
|
|
389
|
-
if
|
|
390
|
-
messages.error(request, "
|
|
393
|
+
if not is_pro:
|
|
394
|
+
messages.error(request, "You need a Pro subscription to add users.")
|
|
395
|
+
elif not user_can_manage_members:
|
|
396
|
+
messages.error(request, "You are not allowed to manage users, contact your organization admin.")
|
|
391
397
|
else:
|
|
392
398
|
user_add_form = UserAddForm(request.POST, organization=organization)
|
|
393
399
|
if user_add_form.is_valid():
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
bom/__init__.py,sha256=HuvSMR9cYQcppTZGD0XjUVUBtHWwWMh1yMQzk_2wTS4,41
|
|
2
2
|
bom/admin.py,sha256=4xN38uSIGo54MVoo2MXUbvcfuPSAifDc8g0arrEAW4Q,4093
|
|
3
3
|
bom/apps.py,sha256=TJMUTSX1h2genPwCq6SN6g1fhrrSmjEXGg2zQFa_ryM,147
|
|
4
|
+
bom/auth_backends.py,sha256=8ViZfP01fITPQnPvsTe_RuKx-ur9dhSOQE3aOp9ESV8,1429
|
|
4
5
|
bom/base_classes.py,sha256=CrWD7wlIkwYb90VoGcVOcw2WoQszRrCje-Re5d_UW1Q,1183
|
|
5
6
|
bom/constants.py,sha256=5CFE0uvKTL91w24rqdAB6EMgpIyw0HhfmmktxF4gCgs,4296
|
|
6
7
|
bom/context_processors.py,sha256=OxMVCqxGtRoHR7aJfTs6xANpxJQzBDUIuNTG1f_Xjoo,312
|
|
@@ -10,7 +11,7 @@ bom/form_fields.py,sha256=tLqchl0j8izBCZnm82NMyHpQV6EuGgCjCl5lrnGR2V0,2816
|
|
|
10
11
|
bom/forms.py,sha256=RUwiMKeaQkapBwz6JCi4Kkl4e5DlFAgSEMjytEDzmoE,69302
|
|
11
12
|
bom/helpers.py,sha256=ONsDM0agG9sKJWMjN4IRNlWx2HNF7T0CXM-ts0GRiAY,15031
|
|
12
13
|
bom/local_settings.py,sha256=yE4aupIquCWsFms44qoCrRrlIyM3sqpOkiwyj1WLxI8,820
|
|
13
|
-
bom/models.py,sha256=
|
|
14
|
+
bom/models.py,sha256=poZoct60kAULCs8RlqC3MFtOl84l2ZfZzjb_d3t9z2g,36537
|
|
14
15
|
bom/part_bom.py,sha256=30HYAKAEhtadiM9tk6vgCQnn7gNJeuXbzF5gXvMvKG4,8720
|
|
15
16
|
bom/settings.py,sha256=jUuy7cKuz9gbZ301L0skMFrnU6qKaBpRUf-rHsTTYJM,8387
|
|
16
17
|
bom/tests.py,sha256=ZqcTUYVXeWjAqzKAV6hp6SKTU0_IOTwIEboTujl7N_M,69905
|
|
@@ -124,6 +125,7 @@ bom/static/bom/js/jquery-3.4.1.min.js,sha256=CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFl
|
|
|
124
125
|
bom/static/bom/js/jquery.ba-floatingscrollbar.min.js,sha256=NptA5rS2zjhkcu26WQJtMr34psHYzUYRsLrSziTusgg,1271
|
|
125
126
|
bom/static/bom/js/jquery.treetable.js,sha256=JEXnh_LuKYxk8CUIT1anQ4es4nfOqC0bds_NjsbMBUI,16611
|
|
126
127
|
bom/static/bom/js/materialize.min.js,sha256=9aWZlbcIvNSnb4BWaUYlFNGylNeTWUL_yffW_3Dbk_o,181114
|
|
128
|
+
bom/templates/bom/_subscription_panel.html,sha256=KE3f4DJ72c93GkW9O6bJw94ht05wNZxORP7o31qafcg,461
|
|
127
129
|
bom/templates/bom/account-delete.html,sha256=YjtG5o-sJHuK4Np3vyEliySF-eAwmFn0ROynDdvPMsU,728
|
|
128
130
|
bom/templates/bom/add-manufacturer-part.html,sha256=gM5_-RfgiuQwfns7s1J006d6ypKMbdG8F_kdLGQrJjA,3242
|
|
129
131
|
bom/templates/bom/add-sellerpart.html,sha256=W9rUYrfpqw3yx45S86GIpepdmN_8Xrf23urYexgObBw,4279
|
|
@@ -135,6 +137,7 @@ bom/templates/bom/bom-base-menu.html,sha256=PeViadG1PKyljvYfPyBFOKgqWhYHBM0tX5Te
|
|
|
135
137
|
bom/templates/bom/bom-base.html,sha256=SvQOyg8ILULjnJKMaYv6Rf4wS8SNXXIjVY2nl5bm7B4,691
|
|
136
138
|
bom/templates/bom/bom-form-modal.html,sha256=U2EWKjOA41jiScKJHXduJJw_hPNGHtYfdiT3yUuwzRY,1389
|
|
137
139
|
bom/templates/bom/bom-form.html,sha256=1oJetm0fJgPAY1zJ2RNv_Pv9MAja2rjz9pO2bR_UA28,1017
|
|
140
|
+
bom/templates/bom/bom-modal-add-users.html,sha256=1lLgj9acgEkYR3AH177D3xj6meWVmq5MwLDyCg5IV5s,2409
|
|
138
141
|
bom/templates/bom/bom-signup.html,sha256=y0z_kQKCDb91ZdexCmUX1NRKH35l-I_N5f2SgO3G2gI,184
|
|
139
142
|
bom/templates/bom/create-part.html,sha256=UjHx6rkPJl-BRt9gKs5zB3s5Y4vrImDTuD25lvABzAI,3610
|
|
140
143
|
bom/templates/bom/dashboard-menu.html,sha256=4MnFSw0x4w7R0CsSwEDFP3FuZVBFxVChIHr58l3rpSk,799
|
|
@@ -157,7 +160,7 @@ bom/templates/bom/part-revision-release.html,sha256=voG7wmYc1Cm3e_H1IasvQcPuyqnn
|
|
|
157
160
|
bom/templates/bom/search-help.html,sha256=Wh_tXBJtz0bznk0F1C7OSdRhMe2qpOs9NMCBb2i0CFI,4398
|
|
158
161
|
bom/templates/bom/seller-info.html,sha256=MACsHMYQXMWfRslXuvh9hD2z28VXzVi0DSy4yg7WQMk,3595
|
|
159
162
|
bom/templates/bom/sellers.html,sha256=6ut7LwRMGUKYB4BRjiSpDBP9BGgqT7nxpNQpUVWDvkw,5412
|
|
160
|
-
bom/templates/bom/settings.html,sha256=
|
|
163
|
+
bom/templates/bom/settings.html,sha256=NNwmlPv2Uk3oaMLm7ESfJ9e9Q7kPFo2y9Q4yfe63O0Y,25452
|
|
161
164
|
bom/templates/bom/signup.html,sha256=tB_x7q3IufSNXsd9Dfh8fdWpkiWSGH2_Zgw749B1PaU,884
|
|
162
165
|
bom/templates/bom/table_of_contents.html,sha256=7wXWOfmVkk5Itjax5x1PE-g5QjxqmYBr7RW8NgtGRng,1763
|
|
163
166
|
bom/templates/bom/upload-bom.html,sha256=qGlI9HoUNe9H2m5T5TqKWGphaNupz3Y0020h_7GebsU,5230
|
|
@@ -175,9 +178,9 @@ bom/third_party_apis/mouser.py,sha256=q2-p0k2n-LNel_QRlfak0kAXT-9hh59k_Pt51PTG09
|
|
|
175
178
|
bom/third_party_apis/test_apis.py,sha256=2W0jtTisGTmktC7l556pn9-pZYseTQmmQfo6_4uP4Dc,679
|
|
176
179
|
bom/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
177
180
|
bom/views/json_views.py,sha256=CaDMxHGnp2182ZV9QZfNkgM7tc_rNmokkelav9rF2dE,2462
|
|
178
|
-
bom/views/views.py,sha256=
|
|
179
|
-
django_bom-1.
|
|
180
|
-
django_bom-1.
|
|
181
|
-
django_bom-1.
|
|
182
|
-
django_bom-1.
|
|
183
|
-
django_bom-1.
|
|
181
|
+
bom/views/views.py,sha256=SvD7Yku9rPwLFmrWC0c15g_a0nC-YkCOnIqEVC32DfU,72267
|
|
182
|
+
django_bom-1.239.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
183
|
+
django_bom-1.239.dist-info/METADATA,sha256=x2kwDE99WQthXTTXKswN4EOHZ2LFAhY9abKJyaAu1jE,7558
|
|
184
|
+
django_bom-1.239.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
185
|
+
django_bom-1.239.dist-info/top_level.txt,sha256=6zytg4lnnobI96dO-ZEadPOCslrrFmf4t2Pnv-y8x0Y,4
|
|
186
|
+
django_bom-1.239.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|