Compare commits

...

2 Commits

Author SHA1 Message Date
Nico Schottelius 95dfe62858 upgrade to python 3.11.1 2023-02-05 21:13:30 +01:00
Nico Schottelius 05eea37349 Cleanup and more demo products 2022-07-16 18:22:52 +02:00
11 changed files with 90 additions and 30 deletions

View File

@ -4,7 +4,7 @@
#
# While trying to install python-ldap
FROM python:3.10.0-alpine3.15
FROM python:3.11.1-alpine3.17
WORKDIR /usr/src/app

View File

@ -1,4 +1,12 @@
all: requirements
IMAGE=ungleich/uncloud
all: requirements build
build:
sh -c 'docker build -t $(IMAGE):$$(git describe) .'
pub: build
docker push $(IMAGE):$$(git describe)
run: requirements
. ./env && python manage.py runserver

View File

@ -12,6 +12,7 @@ machine. Use `kubectl get nodes` to verify minikube is up and running.
* `SECRET_KEY`
* `DEBUG`
* `DATABASE`
* Should be: POSTGRES_HOST, POSTGRES_DB, POSTGRES_USER, POSTRES_PASSWORD
## Versions
@ -35,11 +36,13 @@ machine. Use `kubectl get nodes` to verify minikube is up and running.
* yes: ModelAdmin.formfield_for_manytomany(db_field, request, **kwargs)¶
* resources should have a slug
* can be used as an identifier and non unique names
* Execute collectstatic for docker
#### 3.1 (validation release, planned)
* Ensure that one resource cannot have multiple price_per_timeframe of
the same timeframe
* Add wireguard config support
#### 3.0.2 (planned)
@ -48,13 +51,15 @@ machine. Use `kubectl get nodes` to verify minikube is up and running.
#### 3.0.1 (planned)
NEXT STEP: CREATE THE ORDER AND RESOURCE ORDER OBJECTS
* Show products [done]
* Link to ProductOrderForm [done]
* Find suitable timeframes for a product [done]
* Continue to resources / add resources
* Need to list resources [done]
* Need to create manytomany relations for each resource resoluting
in ResourceOrders1
in ResourceOrders
* Need to pass in the price for the selected timeframe [done]
* On submit
* Create ProductOrder

View File

@ -14,15 +14,22 @@ class ProductOneTimeOrderForm(forms.Form):
for res in resources:
print(res)
field_name = f"{res.slug}"
if res.minimum_units < res.maximum_units:
self.fields[field_name] = forms.FloatField(
required=True,
label=res.name,
min_value=res.minimum_units,
max_value=res.maximum_units,
widget=NumberInput(attrs={"step": res.step_size}))
else:
self.fields[field_name] = forms.FloatField(widget=forms.HiddenInput(attrs={'value': res.minimum_units}))
self.fields[field_name] = forms.FloatField(
required=True,
label=res.name,
min_value=res.minimum_units,
max_value=res.maximum_units,
widget=NumberInput(attrs={"step": res.step_size}))
# if res.minimum_units < res.maximum_units:
# self.fields[field_name] = forms.FloatField(
# required=True,
# label=res.name,
# min_value=res.minimum_units,
# max_value=res.maximum_units,
# widget=NumberInput(attrs={"step": res.step_size}))
# else:
# self.fields[field_name] = forms.FloatField(widget=forms.HiddenInput(attrs={'value': res.minimum_units}))
def clean(self):
cleaned_data = super().clean()
@ -31,7 +38,7 @@ class ProductOneTimeOrderForm(forms.Form):
class ProductOrderForm(ProductOneTimeOrderForm):
"""
For recurring products (might also have OneTime items
For recurring products (might also have OneTime items)
"""
timeframe = forms.SlugField(required=False, disabled=True)

View File

@ -9,12 +9,15 @@ class Command(BaseCommand):
#parser.add_argument('--username', type=str, required=True)
def handle(self, *args, **options):
# Add CHF as currency
currency, created = Currency.objects.get_or_create(defaults=
{
"slug": "CHF",
"name": "Swiss Franc",
"short_name": "CHF"
})
# Add standard timeframes
for timeframe in [ (3600, "1 hour", "1-hour"),
(86400, "1 day", "1-day"),
(7*86400, "7 days", "7-days"),
@ -27,9 +30,16 @@ class Command(BaseCommand):
"seconds": timeframe[0]
})
tf_30d = TimeFrame.objects.get(slug='30-days')
# Add typical prices per timeframe
for ppt in [
("1-day", 1, currency),
("1-day", 2, currency),
("30-days", 2, currency), # HDD 100 GB
("30-days", 3, currency), # CPU
("30-days", 3.5, currency), # SSD Storage
("30-days", 4, currency), # RAM
("30-days", 10, currency), # Nextcloud
("30-days", 15, currency), # Gitea
("30-days", 35, currency), # Matrix
@ -44,32 +54,57 @@ class Command(BaseCommand):
"currency": currency
})
# Add typical resources
for res in [
("cpu-1", "CPU", "Core(s)", None, None),
("cpu-min-max", "CPU", "Core(s)", 1, 20),
("ram-1", "RAM", "GB", None, None),
("ram-min-max", "RAM", "GB", 1, 200),
("matrix-maintenance", "Matrix Maintenance Fee", "", 1, 1),
("nextcloud-maintenance", "Nextcloud Maintenance Fee", "", 1, 1),
("gitea-maintenance", "Gitea Maintenance Fee", "", 1, 1),
# slug name description min max step-size price per 30days
("cpu-1", "CPU", "Core(s)", None, None, 0.5, 3),
("cpu-min-max", "CPU", "Core(s)", 1, 20, 0.5, 3),
("ram-1", "RAM", "GB", None, None, 0.5, 4),
("ram-min-max", "RAM", "GB", 1, 200, 0.5, 4),
("storage-db", "Database-Storage", "GB", 10, None, 10, 3.5),
("storage-ssd", "SSD-Storage", "GB", 10, None, 10, 3.5),
("storage-hdd", "HDD-Storage", "GB", 100, None, 100, 2),
("matrix-maintenance", "Matrix Maintenance Fee", "", 1, 1, None, 35),
("nextcloud-maintenance", "Nextcloud Maintenance Fee", "", 1, 1, None, 10),
("gitea-maintenance", "Gitea Maintenance Fee", "", 1, 1, None, 15),
]:
Resource.objects.get_or_create(slug=res[0],
this_res, created = Resource.objects.get_or_create(slug=res[0],
defaults=
{
"name": res[1],
"unit": res[2],
"minimum_units": res[3],
"maximum_units": res[4]
"maximum_units": res[4],
"step_size": res[5]
})
# If price is given, assign it
if res[6]:
ppt = PricePerTime.objects.get(timeframe=tf_30d, value=res[6])
this_res.price_per_time.add(ppt)
# Link resources to prices per time frame
# Link to PPT -- later
# for ppt_res in res[5]:
# ppt = PricePerTime.objects.get(
# Add test products
for product in [
("matrix", "Matrix"),
("nextcloud", "Nextcloud"),
("gitea", "Gitea") ]:
Product.objects.get_or_create(slug=product[0],
p, created = Product.objects.get_or_create(slug=product[0],
defaults = { "name": product[1] })
for req_res in [ "cpu-min-max",
"ram-min-max",
"storage-db",
"storage-hdd" ]:
print(f"Adding {req_res} to {p}")
p.resources.add(Resource.objects.get(slug=req_res))
p.resources.add(Resource.objects.get(slug=f"{product[0]}-maintenance"))
# Every test product can be bought for the 30d timeframe
p.timeframes.add(tf_30d)

View File

@ -64,8 +64,9 @@ class Resource(models.Model):
step_size = models.FloatField(default=1) # step size
price_per_time = models.ManyToManyField(PricePerTime, blank=True)
#onetime_price = models.ManyToManyField(OneTimePrice, blank=True)
onetime_price = models.ForeignKey(OneTimePrice, null=True, on_delete=models.CASCADE)
onetime_price = models.ForeignKey(OneTimePrice,
null=True, blank=True,
on_delete=models.CASCADE)
def __str__(self):
if self.minimum_units:

View File

@ -8,5 +8,5 @@ you to manage all your resources.
<h2>What can I do with uncloud?</h2>
<ul>
<li>You can<a href="{% url 'products' %}">order products</a></li>
<li>You can <a href="{% url 'products' %}">order products</a></li>
</ul>

View File

@ -9,5 +9,5 @@
<table>
{{ form }}
</table>
<button type="submit" class="btn btn-primary">Submit</button>
<button type="submit" class="btn btn-primary">Order</button>
</form>

View File

@ -97,6 +97,10 @@ class ProductSelectView(CreateView):
fields = ['product' ]
class IndexView(TemplateView):
"""
The starting page containing a short intro
"""
template_name = "app/index.html"
class Yearly(TemplateView):

View File

@ -2,7 +2,7 @@
set -x
name=uncloud:$(git describe)
name=ungleich/uncloud:$(git describe)
docker build -t ${name} .
# check for args

View File

@ -1,4 +1,4 @@
# Django basics
Django==4.0
Django==4.0.5
djangorestframework
django-auth-ldap