django-cfg 1.4.96__py3-none-any.whl → 1.4.97__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.
Potentially problematic release.
This version of django-cfg might be problematic. Click here for more details.
- django_cfg/__init__.py +1 -1
- django_cfg/apps/frontend/views.py +50 -30
- django_cfg/modules/nextjs_admin/views.py +10 -8
- django_cfg/pyproject.toml +1 -1
- django_cfg/templatetags/django_cfg.py +7 -19
- {django_cfg-1.4.96.dist-info → django_cfg-1.4.97.dist-info}/METADATA +1 -1
- {django_cfg-1.4.96.dist-info → django_cfg-1.4.97.dist-info}/RECORD +10 -10
- {django_cfg-1.4.96.dist-info → django_cfg-1.4.97.dist-info}/WHEEL +0 -0
- {django_cfg-1.4.96.dist-info → django_cfg-1.4.97.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.4.96.dist-info → django_cfg-1.4.97.dist-info}/licenses/LICENSE +0 -0
django_cfg/__init__.py
CHANGED
|
@@ -4,8 +4,9 @@ JWT tokens are automatically injected into HTML responses for authenticated user
|
|
|
4
4
|
This is specific to Next.js frontend apps only.
|
|
5
5
|
|
|
6
6
|
Features:
|
|
7
|
-
- Automatic extraction of ZIP archives with
|
|
8
|
-
- Auto-reextraction when ZIP
|
|
7
|
+
- Automatic extraction of ZIP archives with metadata comparison (size + mtime)
|
|
8
|
+
- Auto-reextraction when ZIP content changes (size or timestamp)
|
|
9
|
+
- Marker file (.zip_meta) tracks ZIP metadata for reliable comparison
|
|
9
10
|
- Cache busting (no-store headers for HTML)
|
|
10
11
|
- SPA routing with fallback strategies
|
|
11
12
|
- JWT token injection for authenticated users
|
|
@@ -29,12 +30,13 @@ logger = logging.getLogger(__name__)
|
|
|
29
30
|
|
|
30
31
|
class ZipExtractionMixin:
|
|
31
32
|
"""
|
|
32
|
-
Mixin for automatic ZIP extraction with
|
|
33
|
+
Mixin for automatic ZIP extraction with metadata-based refresh.
|
|
33
34
|
|
|
34
35
|
Provides intelligent ZIP archive handling:
|
|
35
36
|
- Auto-extraction when directory doesn't exist
|
|
36
|
-
- Auto-reextraction when ZIP
|
|
37
|
-
-
|
|
37
|
+
- Auto-reextraction when ZIP metadata changes (size or mtime)
|
|
38
|
+
- Marker file (.zip_meta) tracks ZIP state for reliable comparison
|
|
39
|
+
- Works correctly in Docker where timestamps can be misleading
|
|
38
40
|
|
|
39
41
|
Usage:
|
|
40
42
|
class MyView(ZipExtractionMixin, View):
|
|
@@ -43,12 +45,16 @@ class ZipExtractionMixin:
|
|
|
43
45
|
|
|
44
46
|
def extract_zip_if_needed(self, base_dir: Path, zip_path: Path, app_name: str) -> bool:
|
|
45
47
|
"""
|
|
46
|
-
Extract ZIP archive if needed based on ZIP
|
|
48
|
+
Extract ZIP archive if needed based on ZIP metadata (size + mtime) comparison.
|
|
47
49
|
|
|
48
50
|
Logic:
|
|
49
51
|
1. If directory doesn't exist → extract
|
|
50
|
-
2. If
|
|
51
|
-
3. If
|
|
52
|
+
2. If marker file doesn't exist → extract
|
|
53
|
+
3. If ZIP metadata changed (size or mtime) → remove and re-extract
|
|
54
|
+
4. If metadata matches → use existing
|
|
55
|
+
|
|
56
|
+
Uses marker file (.zip_meta) to track ZIP metadata. More reliable than
|
|
57
|
+
just mtime comparison, especially in Docker where timestamps can be misleading.
|
|
52
58
|
|
|
53
59
|
Args:
|
|
54
60
|
base_dir: Target directory for extraction
|
|
@@ -65,30 +71,40 @@ class ZipExtractionMixin:
|
|
|
65
71
|
logger.error(f"[{app_name}] ZIP not found: {zip_path}")
|
|
66
72
|
return False
|
|
67
73
|
|
|
68
|
-
# Get ZIP
|
|
69
|
-
|
|
74
|
+
# Get ZIP metadata (size + mtime for reliable comparison)
|
|
75
|
+
zip_stat = zip_path.stat()
|
|
76
|
+
current_meta = f"{zip_stat.st_size}:{zip_stat.st_mtime}"
|
|
77
|
+
|
|
78
|
+
# Marker file stores ZIP metadata
|
|
79
|
+
marker_file = base_dir / '.zip_meta'
|
|
70
80
|
|
|
71
81
|
# Priority 1: If directory doesn't exist at all - always extract
|
|
72
82
|
if not base_dir.exists():
|
|
73
83
|
should_extract = True
|
|
74
84
|
logger.info(f"[{app_name}] Directory doesn't exist, will extract")
|
|
75
85
|
|
|
76
|
-
# Priority 2:
|
|
86
|
+
# Priority 2: Marker file doesn't exist - extract (first run or corrupted)
|
|
87
|
+
elif not marker_file.exists():
|
|
88
|
+
should_extract = True
|
|
89
|
+
logger.info(f"[{app_name}] No marker file found, will extract")
|
|
90
|
+
|
|
91
|
+
# Priority 3: Compare stored metadata with current ZIP metadata
|
|
77
92
|
else:
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
logger.
|
|
93
|
+
try:
|
|
94
|
+
stored_meta = marker_file.read_text().strip()
|
|
95
|
+
if stored_meta != current_meta:
|
|
96
|
+
logger.info(f"[{app_name}] ZIP metadata changed (stored: {stored_meta}, current: {current_meta}), re-extracting")
|
|
97
|
+
try:
|
|
98
|
+
shutil.rmtree(base_dir)
|
|
99
|
+
should_extract = True
|
|
100
|
+
except Exception as e:
|
|
101
|
+
logger.error(f"[{app_name}] Failed to remove old directory: {e}")
|
|
102
|
+
return False
|
|
103
|
+
else:
|
|
104
|
+
logger.info(f"[{app_name}] ZIP unchanged (meta: {current_meta}), using existing directory")
|
|
105
|
+
except Exception as e:
|
|
106
|
+
logger.warning(f"[{app_name}] Failed to read marker file: {e}, will re-extract")
|
|
107
|
+
should_extract = True
|
|
92
108
|
|
|
93
109
|
# Extract ZIP if needed
|
|
94
110
|
if should_extract:
|
|
@@ -97,7 +113,10 @@ class ZipExtractionMixin:
|
|
|
97
113
|
base_dir.parent.mkdir(parents=True, exist_ok=True)
|
|
98
114
|
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
|
|
99
115
|
zip_ref.extractall(base_dir)
|
|
100
|
-
|
|
116
|
+
|
|
117
|
+
# Write marker file with current metadata
|
|
118
|
+
marker_file.write_text(current_meta)
|
|
119
|
+
logger.info(f"[{app_name}] Successfully extracted {zip_path.name} and saved marker (meta: {current_meta})")
|
|
101
120
|
return True
|
|
102
121
|
except Exception as e:
|
|
103
122
|
logger.error(f"[{app_name}] Failed to extract: {e}")
|
|
@@ -114,7 +133,7 @@ class NextJSStaticView(ZipExtractionMixin, View):
|
|
|
114
133
|
|
|
115
134
|
Features:
|
|
116
135
|
- Serves Next.js static export files like a static file server
|
|
117
|
-
- Smart ZIP extraction:
|
|
136
|
+
- Smart ZIP extraction: compares ZIP metadata (size + mtime) with marker file
|
|
118
137
|
- Automatically injects JWT tokens for authenticated users
|
|
119
138
|
- Tokens injected into HTML responses only
|
|
120
139
|
- Handles Next.js client-side routing (.html fallback)
|
|
@@ -123,9 +142,10 @@ class NextJSStaticView(ZipExtractionMixin, View):
|
|
|
123
142
|
|
|
124
143
|
ZIP Extraction Logic:
|
|
125
144
|
- If directory doesn't exist: extract from ZIP
|
|
126
|
-
- If
|
|
127
|
-
- If
|
|
128
|
-
-
|
|
145
|
+
- If marker file missing: extract from ZIP
|
|
146
|
+
- If ZIP metadata changed: remove and re-extract
|
|
147
|
+
- If metadata matches: use existing files
|
|
148
|
+
- Marker file (.zip_meta) ensures reliable comparison in Docker
|
|
129
149
|
|
|
130
150
|
Path resolution examples:
|
|
131
151
|
- /cfg/admin/ → /cfg/admin/index.html
|
|
@@ -5,8 +5,8 @@ Serves Next.js static files with SPA routing support and JWT injection.
|
|
|
5
5
|
|
|
6
6
|
Features:
|
|
7
7
|
- Priority-based ZIP resolution (solution project → package fallback)
|
|
8
|
-
- Automatic extraction with
|
|
9
|
-
- Cache busting (no-store headers
|
|
8
|
+
- Automatic extraction with metadata comparison (ZIP size + mtime vs marker file)
|
|
9
|
+
- Cache busting (no-store headers for HTML)
|
|
10
10
|
- SPA routing with fallback strategies
|
|
11
11
|
- JWT token injection for authenticated users
|
|
12
12
|
|
|
@@ -15,8 +15,9 @@ ZIP Resolution Priority:
|
|
|
15
15
|
2. Package fallback: django_cfg/static/frontend/nextjs_admin.zip → django_cfg/static/frontend/nextjs_admin/
|
|
16
16
|
|
|
17
17
|
Extraction Logic:
|
|
18
|
-
-
|
|
19
|
-
- Re-extracts
|
|
18
|
+
- Marker file (.zip_meta) tracks ZIP metadata (size:mtime)
|
|
19
|
+
- Re-extracts when metadata changes (size or timestamp)
|
|
20
|
+
- Reliable in Docker where timestamps can be misleading
|
|
20
21
|
- Ensures fresh builds are deployed automatically
|
|
21
22
|
"""
|
|
22
23
|
|
|
@@ -42,7 +43,7 @@ class NextJsAdminView(ZipExtractionMixin, LoginRequiredMixin, View):
|
|
|
42
43
|
Features:
|
|
43
44
|
- Serves Next.js static build files
|
|
44
45
|
- Priority-based ZIP resolution (solution first, package fallback)
|
|
45
|
-
- Smart ZIP extraction:
|
|
46
|
+
- Smart ZIP extraction: metadata comparison (size + mtime) with marker file
|
|
46
47
|
- Cache busting: no-store headers for HTML files
|
|
47
48
|
- Automatic JWT token injection for authenticated users
|
|
48
49
|
- SPA routing support (path/to/route → path/to/route/index.html)
|
|
@@ -53,9 +54,10 @@ class NextJsAdminView(ZipExtractionMixin, LoginRequiredMixin, View):
|
|
|
53
54
|
|
|
54
55
|
ZIP Extraction Logic:
|
|
55
56
|
- If directory doesn't exist: extract from ZIP
|
|
56
|
-
- If
|
|
57
|
-
- If
|
|
58
|
-
-
|
|
57
|
+
- If marker file missing: extract from ZIP
|
|
58
|
+
- If ZIP metadata changed: remove and re-extract
|
|
59
|
+
- If metadata matches: use existing files
|
|
60
|
+
- Marker file (.zip_meta) ensures reliable comparison in Docker
|
|
59
61
|
|
|
60
62
|
URL Examples:
|
|
61
63
|
/cfg/nextjs-admin/admin/ → admin/index.html
|
django_cfg/pyproject.toml
CHANGED
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "django-cfg"
|
|
7
|
-
version = "1.4.
|
|
7
|
+
version = "1.4.97"
|
|
8
8
|
description = "Modern Django framework with type-safe Pydantic v2 configuration, Next.js admin integration, real-time WebSockets, and 8 enterprise apps. Replace settings.py with validated models, 90% less code. Production-ready with AI agents, auto-generated TypeScript clients, and zero-config features."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
keywords = [ "django", "configuration", "pydantic", "settings", "type-safety", "pydantic-settings", "django-environ", "startup-validation", "ide-autocomplete", "nextjs-admin", "react-admin", "websocket", "centrifugo", "real-time", "typescript-generation", "ai-agents", "enterprise-django", "django-settings", "type-safe-config", "modern-django",]
|
|
@@ -6,7 +6,6 @@ Provides template tags for accessing django-cfg configuration constants.
|
|
|
6
6
|
|
|
7
7
|
import os
|
|
8
8
|
import socket
|
|
9
|
-
import time
|
|
10
9
|
from django import template
|
|
11
10
|
from django.conf import settings
|
|
12
11
|
from django.utils.safestring import mark_safe
|
|
@@ -184,13 +183,9 @@ def nextjs_admin_url(path=''):
|
|
|
184
183
|
# Normalize path - remove leading/trailing slashes
|
|
185
184
|
path = path.strip('/')
|
|
186
185
|
|
|
187
|
-
# Add cache busting parameter (timestamp in milliseconds)
|
|
188
|
-
cache_buster = f'_={int(time.time() * 1000)}'
|
|
189
|
-
|
|
190
186
|
if not settings.DEBUG:
|
|
191
|
-
# Production mode: always use static files
|
|
192
|
-
|
|
193
|
-
return f'{base_url}?{cache_buster}'
|
|
187
|
+
# Production mode: always use static files
|
|
188
|
+
return f'/cfg/admin/{path}' if path else '/cfg/admin/'
|
|
194
189
|
|
|
195
190
|
# Check if port 3001 is available for Tab 1 (built-in admin)
|
|
196
191
|
port_3001_available = _is_port_available('localhost', 3001)
|
|
@@ -198,13 +193,11 @@ def nextjs_admin_url(path=''):
|
|
|
198
193
|
if port_3001_available:
|
|
199
194
|
# Dev server is running on 3001 - use it (builtin admin has no /admin prefix)
|
|
200
195
|
base_url = 'http://localhost:3001'
|
|
201
|
-
|
|
202
|
-
return f'{url}?{cache_buster}'
|
|
196
|
+
return f'{base_url}/{path}' if path else base_url
|
|
203
197
|
else:
|
|
204
|
-
# No dev server or dev server stopped - use static files
|
|
198
|
+
# No dev server or dev server stopped - use static files
|
|
205
199
|
# Static files are served from /cfg/admin/ but ZIP contains files in root (no /admin prefix)
|
|
206
|
-
|
|
207
|
-
return f'{base_url}?{cache_buster}'
|
|
200
|
+
return f'/cfg/admin/{path}' if path else '/cfg/admin/'
|
|
208
201
|
|
|
209
202
|
|
|
210
203
|
@register.simple_tag
|
|
@@ -280,20 +273,15 @@ def nextjs_external_admin_url(route=''):
|
|
|
280
273
|
|
|
281
274
|
route = route.strip('/')
|
|
282
275
|
|
|
283
|
-
# Add cache busting parameter (timestamp in milliseconds)
|
|
284
|
-
cache_buster = f'_={int(time.time() * 1000)}'
|
|
285
|
-
|
|
286
276
|
# Auto-detect development mode: DEBUG=True + port 3000 available
|
|
287
277
|
if settings.DEBUG and _is_port_available('localhost', 3000):
|
|
288
278
|
# Development mode: solution project on port 3000
|
|
289
279
|
# Routes start with /admin in Next.js (e.g., /admin, /admin/crypto)
|
|
290
280
|
base_url = 'http://localhost:3000/admin'
|
|
291
|
-
|
|
292
|
-
return f'{url}?{cache_buster}'
|
|
281
|
+
return f'{base_url}/{route}' if route else base_url
|
|
293
282
|
else:
|
|
294
283
|
# Production mode: use relative URL - Django serves from extracted ZIP with /admin prefix
|
|
295
|
-
|
|
296
|
-
return f'{base_url}?{cache_buster}'
|
|
284
|
+
return f"/cfg/nextjs-admin/admin/{route}" if route else "/cfg/nextjs-admin/admin/"
|
|
297
285
|
except Exception:
|
|
298
286
|
return ''
|
|
299
287
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-cfg
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.97
|
|
4
4
|
Summary: Modern Django framework with type-safe Pydantic v2 configuration, Next.js admin integration, real-time WebSockets, and 8 enterprise apps. Replace settings.py with validated models, 90% less code. Production-ready with AI agents, auto-generated TypeScript clients, and zero-config features.
|
|
5
5
|
Project-URL: Homepage, https://djangocfg.com
|
|
6
6
|
Project-URL: Documentation, https://djangocfg.com
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
django_cfg/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
django_cfg/__init__.py,sha256=
|
|
2
|
+
django_cfg/__init__.py,sha256=_L0rVeRDg_vkLAwSqGT8ka-Mc6eZ0ddniv5wfm9RJvM,1620
|
|
3
3
|
django_cfg/apps.py,sha256=72m3uuvyqGiLx6gOfE-BD3P61jddCCERuBOYpxTX518,1605
|
|
4
4
|
django_cfg/config.py,sha256=y4Z3rnYsHBE0TehpwAIPaxr---mkvyKrZGGsNwYso74,1398
|
|
5
5
|
django_cfg/apps/__init__.py,sha256=JtDmEYt1OcleWM2ZaeX0LKDnRQzPOavfaXBWG4ECB5Q,26
|
|
@@ -228,7 +228,7 @@ django_cfg/apps/frontend/apps.py,sha256=9eEK0Tq2nOsol7xSK5aobdwTDJTJrWx6Iy1I1DQb
|
|
|
228
228
|
django_cfg/apps/frontend/setup.py,sha256=TxKQwQw4xTF6VSyhrQBzbUsdsVQR9JHdjc36LZKeQh4,2444
|
|
229
229
|
django_cfg/apps/frontend/test_routing.py,sha256=fshJOR9ln7m3gXY9EI1_ix_6E5xua6DR264b16RIF-w,4832
|
|
230
230
|
django_cfg/apps/frontend/urls.py,sha256=Vz22_2i2w1J0KQYDCxHnTF5rUf32kUUSBDJZrP07XgY,284
|
|
231
|
-
django_cfg/apps/frontend/views.py,sha256=
|
|
231
|
+
django_cfg/apps/frontend/views.py,sha256=JPTJRPCGY3zLLiiz1F9CsZiLkXbQ5RfnViJZzBUpV7o,15023
|
|
232
232
|
django_cfg/apps/frontend/templates/frontend/404.html,sha256=LCFig_dcgDDmYKhgOLu8R2KDs_aQS6Es6rAxLTAEXWs,2175
|
|
233
233
|
django_cfg/apps/knowbase/README.md,sha256=HXt_J6WCN-LsMhA7p9mdvih07_vp_r_hkPdmqHhNEeo,3965
|
|
234
234
|
django_cfg/apps/knowbase/__init__.py,sha256=cfGnxDQwjajPhUoleKkgvdabJcB0LdXEglnsBojKkPo,1045
|
|
@@ -1021,7 +1021,7 @@ django_cfg/modules/django_unfold/models/navigation.py,sha256=PPEeqA2HBaA1-VjADiX
|
|
|
1021
1021
|
django_cfg/modules/nextjs_admin/__init__.py,sha256=lfrZYyNRExH3Z5De8G4hQBIZoFlW5Ejze3couNrztbY,312
|
|
1022
1022
|
django_cfg/modules/nextjs_admin/apps.py,sha256=HxVUMmWTKdYpwJ00iIfWVFsBzsawsOVhEPZqjk_izjI,347
|
|
1023
1023
|
django_cfg/modules/nextjs_admin/urls.py,sha256=7n0yStm0WNchw14Rtu_mgsIA3WKQsYP9WZt3-YOUWjU,603
|
|
1024
|
-
django_cfg/modules/nextjs_admin/views.py,sha256=
|
|
1024
|
+
django_cfg/modules/nextjs_admin/views.py,sha256=zvRMZZRRcwIA3ie0AEnllOUUwLklbt3nq-P5Eq9BzeY,11385
|
|
1025
1025
|
django_cfg/modules/nextjs_admin/models/__init__.py,sha256=WGw9KXcYd1O9AoA_bpMoz2gLZUlRzjGmUBjjbObcUi0,100
|
|
1026
1026
|
django_cfg/modules/nextjs_admin/models/config.py,sha256=0ADqLuiywSCQfx_z9dkwjFCca3lr3F2uQffIjTr_QXw,5864
|
|
1027
1027
|
django_cfg/modules/nextjs_admin/templatetags/__init__.py,sha256=ChVBnJggCIY8rMhfyJFoA8k0qKo-8FtJknrk54Vx4wM,51
|
|
@@ -1076,7 +1076,7 @@ django_cfg/templates/admin/index.html,sha256=RidRvZwc6LFzRi8l6vHBgyM_CD0yvhPWvr4
|
|
|
1076
1076
|
django_cfg/templates/emails/base_email.html,sha256=TWcvYa2IHShlF_E8jf1bWZStRO0v8G4L_GexPxvz6XQ,8836
|
|
1077
1077
|
django_cfg/templates/unfold/layouts/skeleton.html,sha256=2ArkcNZ34mFs30cOAsTQ1EZiDXcB0aVxkO71lJq9SLE,718
|
|
1078
1078
|
django_cfg/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
1079
|
-
django_cfg/templatetags/django_cfg.py,sha256=
|
|
1079
|
+
django_cfg/templatetags/django_cfg.py,sha256=Q1-dQV8SPOuQu1dFg5eT1gT88eEUXloYMz-7_-OHT0c,9522
|
|
1080
1080
|
django_cfg/utils/__init__.py,sha256=64wwXJuXytvwt8Ze_erSR2HmV07nGWJ6DV5wloRBvYE,435
|
|
1081
1081
|
django_cfg/utils/path_resolution.py,sha256=2n0I04lQkSssFaELu3A93YyMAl1K10KPdpxMt5k4Iy0,13341
|
|
1082
1082
|
django_cfg/utils/smart_defaults.py,sha256=ZUj6K_Deq-fp5O0Dy_Emt257UWFn0f9bkgFv9YCR58U,9239
|
|
@@ -1084,9 +1084,9 @@ django_cfg/utils/version_check.py,sha256=WO51J2m2e-wVqWCRwbultEwu3q1lQasV67Mw2aa
|
|
|
1084
1084
|
django_cfg/CHANGELOG.md,sha256=jtT3EprqEJkqSUh7IraP73vQ8PmKUMdRtznQsEnqDZk,2052
|
|
1085
1085
|
django_cfg/CONTRIBUTING.md,sha256=DU2kyQ6PU0Z24ob7O_OqKWEYHcZmJDgzw-lQCmu6uBg,3041
|
|
1086
1086
|
django_cfg/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
|
|
1087
|
-
django_cfg/pyproject.toml,sha256=
|
|
1088
|
-
django_cfg-1.4.
|
|
1089
|
-
django_cfg-1.4.
|
|
1090
|
-
django_cfg-1.4.
|
|
1091
|
-
django_cfg-1.4.
|
|
1092
|
-
django_cfg-1.4.
|
|
1087
|
+
django_cfg/pyproject.toml,sha256=0AbWzGlCW_MemwzdLfIeySO-sNszpPYNvkPOTe_DUF4,8572
|
|
1088
|
+
django_cfg-1.4.97.dist-info/METADATA,sha256=cb_cXupXvXVnnbikccyCZZwHhzgsBSOa8OWbx76N524,23733
|
|
1089
|
+
django_cfg-1.4.97.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
1090
|
+
django_cfg-1.4.97.dist-info/entry_points.txt,sha256=Ucmde4Z2wEzgb4AggxxZ0zaYDb9HpyE5blM3uJ0_VNg,56
|
|
1091
|
+
django_cfg-1.4.97.dist-info/licenses/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
|
|
1092
|
+
django_cfg-1.4.97.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|