diff --git a/api/__init__.py b/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api/admin.py b/api/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/api/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/api/apps.py b/api/apps.py new file mode 100644 index 0000000..66656fd --- /dev/null +++ b/api/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ApiConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'api' diff --git a/api/mikrotik/api.py b/api/mikrotik/api.py new file mode 100644 index 0000000..85a77e9 --- /dev/null +++ b/api/mikrotik/api.py @@ -0,0 +1,5 @@ +import ros_api + +router = ros_api.Api('192.168.10.1', user='server', password='Cbvgcjy0V', port='8728') +r = router.talk('/interface/wireless/cap/print') +print(r[0]['enabled']) \ No newline at end of file diff --git a/api/mikrotik/total.py b/api/mikrotik/total.py new file mode 100644 index 0000000..9efc179 --- /dev/null +++ b/api/mikrotik/total.py @@ -0,0 +1,15 @@ +import netmiko +from netmiko import ConnectHandler + +mikrotik_router_1 = { +'device_type': 'mikrotik_routeros', +'host': '192.168.10.1', +'port': '2202', +'username': 'server', +'password': 'Cbvgcjy0V' +} + +sshCli = ConnectHandler(**mikrotik_router_1) +print(sshCli.find_prompt()) +output = sshCli.send_command("/interface ethernet print") +print(output) \ No newline at end of file diff --git a/api/models.py b/api/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/api/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/api/serializers.py b/api/serializers.py new file mode 100644 index 0000000..4c35757 --- /dev/null +++ b/api/serializers.py @@ -0,0 +1,15 @@ +from rest_framework import serializers +from django.contrib.auth import get_user_model +User = get_user_model() +from upanel.models import Device,Hostname + +class DeviceSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = Device + fields = ('id','name', 'device_id','device_ip','local_key','device_version','customuser_id') + + +class UserSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = User + fields = ('id','username','email','ipaddress') \ No newline at end of file diff --git a/api/tests.py b/api/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/api/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/api/tuya/__init__.py b/api/tuya/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api/tuya/connect.py b/api/tuya/connect.py new file mode 100644 index 0000000..ec98c06 --- /dev/null +++ b/api/tuya/connect.py @@ -0,0 +1,32 @@ +import psycopg2 +import tinytuya +import json +from tuya_connector import TuyaOpenAPI + +tuya_file='tuya_con.json' + +def connect_base(): + conn = psycopg2.connect(host='172.17.0.1', + port='54322', + user='miroca', + password='cbvgcjy0', + database='miroca') + return conn + + +def connect_local(): + device=tinytuya.deviceScan() + return device + +def connect_tuya(): + ACCESS_ID = "pardyqsmdjetwdxjcaxa" + ACCESS_KEY = "4f81a40a36f349dc9ad11d53d74cb34b" + API_ENDPOINT = "https://openapi.tuyaeu.com" + + try: + openapi = TuyaOpenAPI(API_ENDPOINT, ACCESS_ID, ACCESS_KEY) + openapi.connect() + return openapi + except Exception as e: + with open(tuya_file, 'w', encoding='utf-8') as f: + json.dump([{'error': str(e)}], f,ensure_ascii=False, indent=4) \ No newline at end of file diff --git a/api/tuya/device.py b/api/tuya/device.py new file mode 100644 index 0000000..35a1c6d --- /dev/null +++ b/api/tuya/device.py @@ -0,0 +1,85 @@ +from itertools import chain +from psycopg2.extras import execute_values +from connect import * +import json + +file_psycopd = 'psycopd_con.json' +file_local = 'local_device.json' +file_tuya = 'tuya_con.json' + + +class DeviceError(Exception): + pass + + +def update_base(): + conn = connect_base() + cursor = conn.cursor() + count = 0 + try: + with open(file_tuya, 'r', encoding='utf-8') as f: + tuya_devices = json.load(f) + if tuya_devices['error']: + raise DeviceError(tuya_devices['error']) + except Exception as e: + print(f'Ошибка update_base: {e}') + with open(file_local, 'r', encoding='utf-8') as f: + local_devices = json.load(f) + for device in tuya_devices: + if device['result']['id'] == [v for v in local_devices.values()][count]['gwId']: + cursor.execute("UPDATE upanel_device SET local_key = %s, name = %s " + "WHERE device_id= %s", + (device['result']['local_key'], + device['result']['name'], + device['result']['id'])) + conn.commit() + count += 1 + cursor.close() + + +def add_base(): + conn = connect_base() + cursor = conn.cursor() + try: + with open(file_local, 'r', encoding='utf-8') as f: + local_devices_dict = json.load(f) + local_devices = {i + 1: v for i, v in enumerate(local_devices_dict.values())} + cursor.execute("SELECT * FROM upanel_device") + devices = list(chain.from_iterable(cursor.fetchall())) + execute_values(cursor, "INSERT INTO upanel_device " + "(device_ip, device_id,device_version) " + "VALUES %s", + [(local_devices_dict[local_devices[device]['ip']]['ip'], + local_devices_dict[local_devices[device]['ip']]['gwId'], + local_devices_dict[local_devices[device]['ip']]['version'],) + for device in local_devices if local_devices[device]['ip'] not in devices]) + conn.commit() + cursor.close() + except Exception as e: + print(f'ошибка add_base: {e}') + with open('error_add.json', 'w', encoding='utf-8') as f: + json.dump({'Error_add':e}, f) + +def delete_base(): + conn = connect_base() + cursor = conn.cursor() + try: + with open(file_local, 'r', encoding='utf-8') as f: + local_devices_dict = json.load(f) + ip_file=sorted([v for k,v in enumerate(local_devices_dict)]) + cursor.execute('SELECT * FROM upanel_device') + cursor.executemany("DELETE FROM upanel_device WHERE device_ip=%s", + [tuple(str(item) for item in ip[2].split()) + for ip in cursor.fetchall() + if ip[2] not in ip_file]) + conn.commit() + + except Exception as e: + print(f'Ошибка delete_base: {e}') + with open('error_delete.json', 'w', encoding='utf-8') as f: + json.dump({'Error_delete':e}, f) + +if __name__ == '__main__': + add_base() + update_base() + delete_base() diff --git a/api/tuya/input_file.py b/api/tuya/input_file.py new file mode 100644 index 0000000..d32b778 --- /dev/null +++ b/api/tuya/input_file.py @@ -0,0 +1,44 @@ +from connect import * + +psycopd_file = 'psycopd_con.json' +local_file = 'local_device.json' +tuya_file='tuya_con.json' + +def file_base(): + try: + cursor=connect_base().cursor() + cursor.execute('SELECT * FROM upanel_device') + except Exception as e: + with open(psycopd_file, 'w', encoding='utf-8') as f: + json.dump({'error': str(e)}, f) + else: + with open(psycopd_file, 'w', encoding='utf-8') as f: + json.dump({v[0]:v[1:] for k,v in enumerate(cursor.fetchall())}, f, + ensure_ascii=False, indent=4) + + + +def file_local(): + try: + with open(local_file, 'w', encoding='utf-8') as f: + json.dump(connect_local(), f, ensure_ascii=False, indent=4) + except Exception as e: + with open(local_file, 'w', encoding='utf-8') as f: + json.dump({'error': str(e)}, f) + + +def file_tuya(): + try: + with open(local_file, 'r', encoding='utf-8') as f: + local_device = json.load(f) + with open(tuya_file, 'w', encoding='utf-8') as f: + json.dump([connect_tuya().get(f"/v1.0/iot-03/devices/{local_device[dev]['id']}") + for dev in local_device],f,ensure_ascii=False, indent=4) + except Exception as e: + with open(tuya_file, 'w', encoding='utf-8') as f: + json.dump({'error': str(e)}, f) + +if __name__ == '__main__': + file_base() + file_local() + file_tuya() \ No newline at end of file diff --git a/api/urls.py b/api/urls.py new file mode 100644 index 0000000..b6fd8f8 --- /dev/null +++ b/api/urls.py @@ -0,0 +1,12 @@ +from django.urls import path,include +from rest_framework.routers import DefaultRouter +from api import views + +router = DefaultRouter() +router.register(r'devices', views.DeviceViewSet) +router.register(r'user', views.UserViewSet) + +urlpatterns = [ + path('', include((router.urls, 'app_name'), namespace='api/device')), + path('', include((router.urls, 'app_name'), namespace='api/user')), +] diff --git a/api/views.py b/api/views.py new file mode 100644 index 0000000..6b6e41c --- /dev/null +++ b/api/views.py @@ -0,0 +1,24 @@ +from django.shortcuts import render +from django.contrib.auth import get_user_model +User = get_user_model() +from rest_framework import viewsets +from api.serializers import DeviceSerializer,UserSerializer +from upanel.models import * + +from rest_framework.authentication import BasicAuthentication +from rest_framework.permissions import IsAuthenticated + + + +class DeviceViewSet(viewsets.ModelViewSet): + authentication_classes = (BasicAuthentication,) + permission_classes = (IsAuthenticated,) + queryset = Device.objects.values().order_by('id') + serializer_class = DeviceSerializer + + +class UserViewSet(viewsets.ModelViewSet): + authentication_classes = (BasicAuthentication,) + permission_classes = (IsAuthenticated,) + queryset = User.objects.values().order_by('id') + serializer_class = UserSerializer diff --git a/auth_miroca/__init__.py b/auth_miroca/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/auth_miroca/admin.py b/auth_miroca/admin.py new file mode 100644 index 0000000..55b90f2 --- /dev/null +++ b/auth_miroca/admin.py @@ -0,0 +1,26 @@ +from django.contrib import admin +from django.contrib.auth.admin import UserAdmin +from .forms import CustomUserCreationForm, CustomUserChangeForm +from .models import CustomUser + +class CustomUserAdmin(UserAdmin): + add_form = CustomUserCreationForm + form = CustomUserChangeForm + model = CustomUser + list_display = ('email', 'is_superuser','is_staff', 'is_active',) + list_filter = ('email','is_superuser','is_staff', 'is_active',) + fieldsets = ( + (None, {'fields': ('email', 'password')}), + ('Разрешения', {'fields': ('is_superuser','is_staff','is_active','groups',)}), + ('Пользователь',{'fields':('username','last_name','first_name','phone','org','address')}), + ('Регистрация и вход', {'fields': ('date_joined','last_login')}), + ) + add_fieldsets = ( + (None, { + 'classes': ('wide',), + 'fields': ('email','is_superuser', 'password1', 'password2', 'is_staff', 'is_active')} + ), + ) + search_fields = ('email',) + ordering = ('email',) +admin.site.register(CustomUser, CustomUserAdmin) \ No newline at end of file diff --git a/auth_miroca/apps.py b/auth_miroca/apps.py new file mode 100644 index 0000000..cf3c29e --- /dev/null +++ b/auth_miroca/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class AuthMirocaConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'auth_miroca' diff --git a/auth_miroca/forms.py b/auth_miroca/forms.py new file mode 100644 index 0000000..15cf555 --- /dev/null +++ b/auth_miroca/forms.py @@ -0,0 +1,10 @@ +from django.contrib.auth.forms import UserCreationForm, UserChangeForm +from .models import CustomUser +class CustomUserCreationForm(UserCreationForm): + class Meta(UserCreationForm): + model = CustomUser + fields = ('email',) +class CustomUserChangeForm(UserChangeForm): + class Meta: + model = CustomUser + fields = ('email',) \ No newline at end of file diff --git a/auth_miroca/logout.py b/auth_miroca/logout.py new file mode 100644 index 0000000..a6acdfd --- /dev/null +++ b/auth_miroca/logout.py @@ -0,0 +1,9 @@ +from django.shortcuts import render, redirect + +def logout_view(func): + def wrapper(request): + if request.method == 'POST': + request.session.clear() + return redirect ('login') + return func(request) + return wrapper \ No newline at end of file diff --git a/auth_miroca/managers.py b/auth_miroca/managers.py new file mode 100644 index 0000000..2e2ffd5 --- /dev/null +++ b/auth_miroca/managers.py @@ -0,0 +1,34 @@ +from django.contrib.auth.base_user import BaseUserManager +from django.utils.translation import gettext_lazy as _ + + +class CustomUserManager(BaseUserManager): + """ + Custom user model manager where email is the unique identifiers + for authentication instead of usernames. + """ + def create_user(self, email, password, **extra_fields): + """ + Create and save a user with the given email and password. + """ + if not email: + raise ValueError(_("The Email must be set")) + email = self.normalize_email(email) + user = self.model(email=email, **extra_fields) + user.set_password(password) + user.save() + return user + + def create_superuser(self, email, password, **extra_fields): + """ + Create and save a SuperUser with the given email and password. + """ + extra_fields.setdefault("is_staff", True) + extra_fields.setdefault("is_superuser", True) + extra_fields.setdefault("is_active", True) + + if extra_fields.get("is_staff") is not True: + raise ValueError(_("Superuser must have is_staff=True.")) + if extra_fields.get("is_superuser") is not True: + raise ValueError(_("Superuser must have is_superuser=True.")) + return self.create_user(email, password, **extra_fields) \ No newline at end of file diff --git a/auth_miroca/migrations/0001_initial.py b/auth_miroca/migrations/0001_initial.py new file mode 100644 index 0000000..dcb8a5e --- /dev/null +++ b/auth_miroca/migrations/0001_initial.py @@ -0,0 +1,37 @@ +# Generated by Django 5.1.3 on 2024-11-29 06:19 + +import django.utils.timezone +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ] + + operations = [ + migrations.CreateModel( + name='CustomUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('email', models.EmailField(max_length=254, unique=True, verbose_name='email address')), + ('is_staff', models.BooleanField(default=False, verbose_name='Персонал')), + ('is_active', models.BooleanField(default=True, verbose_name='Активный')), + ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), + ('username', models.CharField(max_length=255, null=True, verbose_name='username')), + ('image', models.ImageField(blank=True, null=True, upload_to='user/%Y/%m/%d', verbose_name='Изображение')), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')), + ], + options={ + 'verbose_name': ('user',), + 'verbose_name_plural': 'Пользователь', + }, + ), + ] diff --git a/auth_miroca/migrations/0002_customuser_ipaddress.py b/auth_miroca/migrations/0002_customuser_ipaddress.py new file mode 100644 index 0000000..44bed51 --- /dev/null +++ b/auth_miroca/migrations/0002_customuser_ipaddress.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.3 on 2024-11-29 12:46 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('auth_miroca', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='customuser', + name='ipaddress', + field=models.GenericIPAddressField(null=True), + ), + ] diff --git a/auth_miroca/migrations/0003_customuser_last_name_customuser_phone.py b/auth_miroca/migrations/0003_customuser_last_name_customuser_phone.py new file mode 100644 index 0000000..49b4b9a --- /dev/null +++ b/auth_miroca/migrations/0003_customuser_last_name_customuser_phone.py @@ -0,0 +1,24 @@ +# Generated by Django 5.1.3 on 2024-11-29 12:53 + +import phone_field.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('auth_miroca', '0002_customuser_ipaddress'), + ] + + operations = [ + migrations.AddField( + model_name='customuser', + name='last_name', + field=models.CharField(max_length=255, null=True, verbose_name='Фамилия'), + ), + migrations.AddField( + model_name='customuser', + name='phone', + field=phone_field.models.PhoneField(blank=True, help_text='Контактный номер', max_length=31, null=True), + ), + ] diff --git a/auth_miroca/migrations/0004_customuser_address_customuser_first_name.py b/auth_miroca/migrations/0004_customuser_address_customuser_first_name.py new file mode 100644 index 0000000..a29e12f --- /dev/null +++ b/auth_miroca/migrations/0004_customuser_address_customuser_first_name.py @@ -0,0 +1,26 @@ +# Generated by Django 5.1.3 on 2024-11-29 13:00 + +import address.models +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('address', '0003_auto_20200830_1851'), + ('auth_miroca', '0003_customuser_last_name_customuser_phone'), + ] + + operations = [ + migrations.AddField( + model_name='customuser', + name='address', + field=address.models.AddressField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='address.address', verbose_name='Адрес'), + ), + migrations.AddField( + model_name='customuser', + name='first_name', + field=models.CharField(max_length=255, null=True, verbose_name='Имя'), + ), + ] diff --git a/auth_miroca/migrations/0005_alter_customuser_address.py b/auth_miroca/migrations/0005_alter_customuser_address.py new file mode 100644 index 0000000..d7ef8eb --- /dev/null +++ b/auth_miroca/migrations/0005_alter_customuser_address.py @@ -0,0 +1,21 @@ +# Generated by Django 5.1.3 on 2024-11-29 13:02 + +import address.models +import django.db.models.deletion +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('address', '0003_auto_20200830_1851'), + ('auth_miroca', '0004_customuser_address_customuser_first_name'), + ] + + operations = [ + migrations.AlterField( + model_name='customuser', + name='address', + field=address.models.AddressField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='address.address', verbose_name='Адрес'), + ), + ] diff --git a/auth_miroca/migrations/0006_remove_customuser_address.py b/auth_miroca/migrations/0006_remove_customuser_address.py new file mode 100644 index 0000000..0c6d8cd --- /dev/null +++ b/auth_miroca/migrations/0006_remove_customuser_address.py @@ -0,0 +1,17 @@ +# Generated by Django 5.1.3 on 2024-11-29 13:05 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('auth_miroca', '0005_alter_customuser_address'), + ] + + operations = [ + migrations.RemoveField( + model_name='customuser', + name='address', + ), + ] diff --git a/auth_miroca/migrations/0007_customuser_ipaddress_mikrotik.py b/auth_miroca/migrations/0007_customuser_ipaddress_mikrotik.py new file mode 100644 index 0000000..91ef599 --- /dev/null +++ b/auth_miroca/migrations/0007_customuser_ipaddress_mikrotik.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.3 on 2024-11-29 16:51 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('auth_miroca', '0006_remove_customuser_address'), + ] + + operations = [ + migrations.AddField( + model_name='customuser', + name='ipaddress_mikrotik', + field=models.GenericIPAddressField(null=True), + ), + ] diff --git a/auth_miroca/migrations/0008_remove_customuser_ipaddress_mikrotik.py b/auth_miroca/migrations/0008_remove_customuser_ipaddress_mikrotik.py new file mode 100644 index 0000000..8a0b184 --- /dev/null +++ b/auth_miroca/migrations/0008_remove_customuser_ipaddress_mikrotik.py @@ -0,0 +1,17 @@ +# Generated by Django 5.1.3 on 2024-11-29 17:28 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('auth_miroca', '0007_customuser_ipaddress_mikrotik'), + ] + + operations = [ + migrations.RemoveField( + model_name='customuser', + name='ipaddress_mikrotik', + ), + ] diff --git a/auth_miroca/migrations/__init__.py b/auth_miroca/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/auth_miroca/models.py b/auth_miroca/models.py new file mode 100644 index 0000000..305f5a7 --- /dev/null +++ b/auth_miroca/models.py @@ -0,0 +1,33 @@ +from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin +from django.db import models +from django.utils import timezone +from django.utils.translation import gettext_lazy as _ +from phone_field import PhoneField +from address.models import AddressField + +from .managers import CustomUserManager + + +class CustomUser(AbstractBaseUser, PermissionsMixin): + email = models.EmailField(_("email address"), unique=True) + is_staff = models.BooleanField(default=False, verbose_name='Персонал') + is_active = models.BooleanField(default=True, verbose_name='Активный') + date_joined = models.DateTimeField(_('date joined'), default=timezone.now) + username = models.CharField(max_length=255, null=True, verbose_name='username') + image = models.ImageField(upload_to='user/%Y/%m/%d', blank=True, null=True, verbose_name='Изображение') + ipaddress=models.GenericIPAddressField(null=True) + last_name=models.CharField(max_length=255, null=True,verbose_name='Фамилия') + first_name=models.CharField(max_length=255,null=True,verbose_name='Имя') + phone = PhoneField(blank=True,null=True, help_text='Контактный номер') + + USERNAME_FIELD = 'email' + REQUIRED_FIELDS = [] + + objects = CustomUserManager() + + def __str__(self): + return self.email + + class Meta: + verbose_name = 'user', + verbose_name_plural = 'Пользователь' diff --git a/auth_miroca/tests.py b/auth_miroca/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/auth_miroca/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/auth_miroca/views.py b/auth_miroca/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/auth_miroca/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/home/__init__.py b/home/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/home/admin.py b/home/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/home/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/home/apps.py b/home/apps.py new file mode 100644 index 0000000..e5ea0af --- /dev/null +++ b/home/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class HomeConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'home' diff --git a/home/models.py b/home/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/home/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/home/tests.py b/home/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/home/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/home/views.py b/home/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/home/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/kiosk/__init__.py b/kiosk/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kiosk/admin.py b/kiosk/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/kiosk/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/kiosk/models.py b/kiosk/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/kiosk/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/kiosk/templates/kiosk/base/base.html b/kiosk/templates/kiosk/base/base.html new file mode 100644 index 0000000..b68b739 --- /dev/null +++ b/kiosk/templates/kiosk/base/base.html @@ -0,0 +1,69 @@ + +{% load static %} + +
+ + + +