summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'python/bb_dashboard')
-rw-r--r--python/bb_dashboard/bb_dashboard/__init__.py0
-rw-r--r--python/bb_dashboard/bb_dashboard/asgi.py16
-rw-r--r--python/bb_dashboard/bb_dashboard/settings.py.sample149
-rw-r--r--python/bb_dashboard/bb_dashboard/urls.py9
-rw-r--r--python/bb_dashboard/bb_dashboard/wsgi.py16
-rwxr-xr-xpython/bb_dashboard/manage.py22
-rw-r--r--python/bb_dashboard/projects/__init__.py0
-rw-r--r--python/bb_dashboard/projects/admin.py3
-rw-r--r--python/bb_dashboard/projects/apps.py6
-rw-r--r--python/bb_dashboard/projects/migrations/__init__.py0
-rw-r--r--python/bb_dashboard/projects/models.py3
-rw-r--r--python/bb_dashboard/projects/tests.py3
-rw-r--r--python/bb_dashboard/projects/views.py3
-rw-r--r--python/bb_dashboard/repository/__init__.py0
-rw-r--r--python/bb_dashboard/repository/admin.py3
-rw-r--r--python/bb_dashboard/repository/apps.py6
-rw-r--r--python/bb_dashboard/repository/migrations/__init__.py0
-rw-r--r--python/bb_dashboard/repository/models.py45
-rw-r--r--python/bb_dashboard/repository/tests.py3
-rw-r--r--python/bb_dashboard/repository/views.py3
-rw-r--r--python/bb_dashboard/static/screen.css3
-rw-r--r--python/bb_dashboard/templates/includes/container/end3
-rw-r--r--python/bb_dashboard/templates/includes/container/start3
-rw-r--r--python/bb_dashboard/templates/includes/layout/footer.html43
-rw-r--r--python/bb_dashboard/templates/includes/layout/head.html26
-rw-r--r--python/bb_dashboard/templates/includes/layout/header.html89
-rw-r--r--python/bb_dashboard/templates/includes/navigation/primary10
-rw-r--r--python/bb_dashboard/templates/includes/navigation/secondary10
-rw-r--r--python/bb_dashboard/templates/layout/base.html20
-rw-r--r--python/bb_dashboard/www/__init__.py0
-rw-r--r--python/bb_dashboard/www/admin.py7
-rw-r--r--python/bb_dashboard/www/apps.py6
-rw-r--r--python/bb_dashboard/www/migrations/0001_initial.py95
-rw-r--r--python/bb_dashboard/www/migrations/__init__.py0
-rw-r--r--python/bb_dashboard/www/models.py74
-rw-r--r--python/bb_dashboard/www/router.py31
-rw-r--r--python/bb_dashboard/www/templates/www/index.html42
-rw-r--r--python/bb_dashboard/www/templates/www/news.html20
-rw-r--r--python/bb_dashboard/www/tests.py3
-rw-r--r--python/bb_dashboard/www/urls.py7
-rw-r--r--python/bb_dashboard/www/utils.py55
-rw-r--r--python/bb_dashboard/www/views.py16
42 files changed, 853 insertions, 0 deletions
diff --git a/python/bb_dashboard/bb_dashboard/__init__.py b/python/bb_dashboard/bb_dashboard/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/python/bb_dashboard/bb_dashboard/__init__.py
diff --git a/python/bb_dashboard/bb_dashboard/asgi.py b/python/bb_dashboard/bb_dashboard/asgi.py
new file mode 100644
index 0000000..1e2115c
--- /dev/null
+++ b/python/bb_dashboard/bb_dashboard/asgi.py
@@ -0,0 +1,16 @@
+"""
+ASGI config for bb_dashboard project.
+
+It exposes the ASGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/
+"""
+
+import os
+
+from django.core.asgi import get_asgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'bb_dashboard.settings')
+
+application = get_asgi_application()
diff --git a/python/bb_dashboard/bb_dashboard/settings.py.sample b/python/bb_dashboard/bb_dashboard/settings.py.sample
new file mode 100644
index 0000000..079368e
--- /dev/null
+++ b/python/bb_dashboard/bb_dashboard/settings.py.sample
@@ -0,0 +1,149 @@
+"""
+Django settings for bb_dashboard project.
+
+Generated by 'django-admin startproject' using Django 3.2.3.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/3.2/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/3.2/ref/settings/
+"""
+
+from pathlib import Path
+
+# Build paths inside the project like this: BASE_DIR / 'subdir'.
+BASE_DIR = Path(__file__).resolve().parent.parent
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = 'fooo'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+ALLOWED_HOSTS = [
+ '.localhost',
+ '127.0.0.1',
+ '[::1]',
+ ]
+
+
+# Application definition
+
+INSTALLED_APPS = [
+ 'django.contrib.admin',
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.messages',
+ 'django.contrib.staticfiles',
+ 'www.apps.WwwConfig',
+]
+
+MIDDLEWARE = [
+ 'django.middleware.security.SecurityMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+]
+
+ROOT_URLCONF = 'bb_dashboard.urls'
+
+TEMPLATES = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': [
+ 'templates',
+ ],
+ 'APP_DIRS': True,
+ 'OPTIONS': {
+ 'context_processors': [
+ 'django.template.context_processors.debug',
+ 'django.template.context_processors.request',
+ 'django.contrib.auth.context_processors.auth',
+ 'django.contrib.messages.context_processors.messages',
+ ],
+ },
+ },
+]
+
+WSGI_APPLICATION = 'bb_dashboard.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.postgresql',
+ 'NAME': '',
+ 'USER': '',
+ 'PASSWORD': '',
+ 'HOST': '',
+ 'PORT': '',
+ },
+ 'gentoo-ci': {
+ 'ENGINE': 'django.db.backends.postgresql',
+ 'NAME': '',
+ 'USER': '',
+ 'PASSWORD': '',
+ 'HOST': '',
+ 'PORT': '',
+ }
+}
+
+DATABASE_ROUTERS = ['www.router.WWWRouter']
+
+# Password validation
+# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+ {
+ 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+ },
+]
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/3.2/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'Europe/Stockholm'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/3.2/howto/static-files/
+
+STATIC_URL = '/static/'
+
+STATICFILES_DIRS = [
+ BASE_DIR / "static",
+]
+
+# Default primary key field type
+# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
+
+DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
diff --git a/python/bb_dashboard/bb_dashboard/urls.py b/python/bb_dashboard/bb_dashboard/urls.py
new file mode 100644
index 0000000..f1e4c86
--- /dev/null
+++ b/python/bb_dashboard/bb_dashboard/urls.py
@@ -0,0 +1,9 @@
+from django.contrib import admin
+from django.urls import include, path
+
+urlpatterns = [
+ path('www/', include('www.urls')),
+ #path('auth/', include('gosbs_auth.urls')),
+ #path('projects/', include('projects.urls', namespace="projects")),
+ #path('admin/', admin.site.urls),
+]
diff --git a/python/bb_dashboard/bb_dashboard/wsgi.py b/python/bb_dashboard/bb_dashboard/wsgi.py
new file mode 100644
index 0000000..cf71243
--- /dev/null
+++ b/python/bb_dashboard/bb_dashboard/wsgi.py
@@ -0,0 +1,16 @@
+"""
+WSGI config for bb_dashboard project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'bb_dashboard.settings')
+
+application = get_wsgi_application()
diff --git a/python/bb_dashboard/manage.py b/python/bb_dashboard/manage.py
new file mode 100755
index 0000000..8a6e55f
--- /dev/null
+++ b/python/bb_dashboard/manage.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+"""Django's command-line utility for administrative tasks."""
+import os
+import sys
+
+
+def main():
+ """Run administrative tasks."""
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'bb_dashboard.settings')
+ try:
+ from django.core.management import execute_from_command_line
+ except ImportError as exc:
+ raise ImportError(
+ "Couldn't import Django. Are you sure it's installed and "
+ "available on your PYTHONPATH environment variable? Did you "
+ "forget to activate a virtual environment?"
+ ) from exc
+ execute_from_command_line(sys.argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/python/bb_dashboard/projects/__init__.py b/python/bb_dashboard/projects/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/python/bb_dashboard/projects/__init__.py
diff --git a/python/bb_dashboard/projects/admin.py b/python/bb_dashboard/projects/admin.py
new file mode 100644
index 0000000..8c38f3f
--- /dev/null
+++ b/python/bb_dashboard/projects/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/python/bb_dashboard/projects/apps.py b/python/bb_dashboard/projects/apps.py
new file mode 100644
index 0000000..afae498
--- /dev/null
+++ b/python/bb_dashboard/projects/apps.py
@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class ProjectsConfig(AppConfig):
+ default_auto_field = 'django.db.models.BigAutoField'
+ name = 'projects'
diff --git a/python/bb_dashboard/projects/migrations/__init__.py b/python/bb_dashboard/projects/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/python/bb_dashboard/projects/migrations/__init__.py
diff --git a/python/bb_dashboard/projects/models.py b/python/bb_dashboard/projects/models.py
new file mode 100644
index 0000000..71a8362
--- /dev/null
+++ b/python/bb_dashboard/projects/models.py
@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.
diff --git a/python/bb_dashboard/projects/tests.py b/python/bb_dashboard/projects/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/python/bb_dashboard/projects/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/python/bb_dashboard/projects/views.py b/python/bb_dashboard/projects/views.py
new file mode 100644
index 0000000..91ea44a
--- /dev/null
+++ b/python/bb_dashboard/projects/views.py
@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.
diff --git a/python/bb_dashboard/repository/__init__.py b/python/bb_dashboard/repository/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/python/bb_dashboard/repository/__init__.py
diff --git a/python/bb_dashboard/repository/admin.py b/python/bb_dashboard/repository/admin.py
new file mode 100644
index 0000000..8c38f3f
--- /dev/null
+++ b/python/bb_dashboard/repository/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/python/bb_dashboard/repository/apps.py b/python/bb_dashboard/repository/apps.py
new file mode 100644
index 0000000..9c086eb
--- /dev/null
+++ b/python/bb_dashboard/repository/apps.py
@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class RepositoryConfig(AppConfig):
+ default_auto_field = 'django.db.models.BigAutoField'
+ name = 'repository'
diff --git a/python/bb_dashboard/repository/migrations/__init__.py b/python/bb_dashboard/repository/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/python/bb_dashboard/repository/migrations/__init__.py
diff --git a/python/bb_dashboard/repository/models.py b/python/bb_dashboard/repository/models.py
new file mode 100644
index 0000000..a7989bc
--- /dev/null
+++ b/python/bb_dashboard/repository/models.py
@@ -0,0 +1,45 @@
+from django.db import models
+
+class Categories(models.Model):
+ CategoryId = models.IntegerField(primary_key=True, db_column='category_id')
+ Category = models.CharField(max_length=150, db_column='category')
+ Active = models.BooleanField(db_column='active')
+ TimeStamp = models.DateTimeField(db_column='time_stamp')
+ class Meta:
+ db_table = 'categories'
+ def __str__(self):
+ return '%s %s %s %s' % (self.CategoryId, self.Category, self.Active, self.TimeStamp)
+
+class Repos(models.Model):
+ RepoId = models.IntegerField(primary_key=True, db_column='repo_id')
+ Repo = models.CharField(max_length=100, db_column='repo')
+ class Meta:
+ db_table = 'repos'
+ def __str__(self):
+ return '%s %s' % (self.RepoId, self.Repo)
+
+class Packages(models.Model):
+ PackageId = models.IntegerField(primary_key=True, db_column='package_id')
+ CategoryId = models.ForeignKey(Categories, db_column='category_id')
+ Package = models.CharField(max_length=150, db_column='package')
+ RepoId = models.ForeignKey(Repos, db_column='repo_id')
+ Checksum = models.CharField(max_length=100, db_column='checksum')
+ Active = models.BooleanField(db_column='active')
+ TimeStamp = models.DateTimeField(db_column='time_stamp')
+ class Meta:
+ db_table = 'packages'
+ def __str__(self):
+ return '%s %s %s %s %s %s %s' % (self.PackageId, self.CategoryId, self.Package, self.RepoId, self.Checksum, self.Active, self.TimeStamp)
+
+class Ebuilds(models.Model):
+ EbuildId = models.IntegerField(primary_key=True, db_column='ebuild_id')
+ PackageId = models.ForeignKey(Packages, db_column='package_id')
+ Version = models.CharField(max_length=150, db_column='version')
+ Checksum = models.CharField(max_length=100, db_column='checksum')
+ Active = models.BooleanField(db_column='active')
+ TimeStamp = models.DateTimeField(db_column='time_stamp')
+ class Meta:
+ db_table = 'ebuilds'
+ def __str__(self):
+ return '%s %s %s %s %s %s' % (self.EbuildId, self.PackageId, self.Version, self.Checksum, self.Active, self.TimeStamp)
+
diff --git a/python/bb_dashboard/repository/tests.py b/python/bb_dashboard/repository/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/python/bb_dashboard/repository/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/python/bb_dashboard/repository/views.py b/python/bb_dashboard/repository/views.py
new file mode 100644
index 0000000..91ea44a
--- /dev/null
+++ b/python/bb_dashboard/repository/views.py
@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.
diff --git a/python/bb_dashboard/static/screen.css b/python/bb_dashboard/static/screen.css
new file mode 100644
index 0000000..b0470e8
--- /dev/null
+++ b/python/bb_dashboard/static/screen.css
@@ -0,0 +1,3 @@
+.devmap-entry{background-color:#f7f7f7;border:1px solid #e1e1e1;border-radius:4px;padding:8px;margin-bottom:4px;max-width:300px}.devmap-entry h3 small{color:#333;font-size:80%;mmargin-left:1em}.download-size{margin-left:1em}.download-tag{margin-left:1em}.stick-top{margin-top:0}@media (min-width: 768px){.other-arches .tab-pane{margin-left:1em}}ul.sitemap{padding-left:1em}ul.sitemap li{list-style-type:none}@media (min-width: 768px){.container-sitemap{padding-top:1em;margin-top:1em;margin-bottom:1em}}@media (min-width: 992px){.container-sitemap{border-top:1px solid #d5d5d5;border-bottom:1px solid #d5d5d5}}.footer-breadcrumb{margin-top:2em}.hero-section{background-size:cover;background-repeat:no-repeat;min-height:200px;font-size:120%;padding-top:2%;padding-bottom:2%}@media (min-width: 768px){.hero-section{font-size:150%}.hero-section h2{font-size:130%}}.get-started-livecd{color:black;background-color:#B0BEC5}.get-started-handbook{color:black;background-color:#90A4AE;margin-top:-1px}.get-started-go{color:white;background-color:#54487a;margin-top:-1px}.emergehdr{margin-top:-21px;background-color:#54487a;background-image:url("https://www.gentoo.org/assets/img/bg/emerge.jpg");cursor:default;min-height:0;box-shadow:0px 0px 5px #333;padding-top:1em;padding-bottom:1em}@media (min-width: 992px){.emergehdr{font-size:1.95em}}.emergehdr p{text-shadow:0px 0px 5px black;color:white;margin:0}.emergehdr .buttons{margin-top:3px}.abouthdr{background:#c2bcd6;background:-moz-linear-gradient(-45deg, #c2bcd6 0%, #53487a 43%, #53487a 100%);background:-webkit-gradient(left top, right bottom, color-stop(0%, #c2bcd6), color-stop(43%, #53487a), color-stop(100%, #53487a));background:-webkit-linear-gradient(-45deg, #c2bcd6 0%, #53487a 43%, #53487a 100%);background:-o-linear-gradient(-45deg, #c2bcd6 0%, #53487a 43%, #53487a 100%);background:-ms-linear-gradient(-45deg, #c2bcd6 0%, #53487a 43%, #53487a 100%);background:linear-gradient(135deg, #c2bcd6 0%, #53487a 43%, #53487a 100%);filter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#c2bcd6', endColorstr='#53487a', GradientType=1 );bbackground-size:cover;bbackground-repeat:no-repeat;bbackground-image:url("/assets/img/bg/larry-about.jpg");min-height:300px;color:white}.abouthdr .right{text-align:right;margin-right:20%}.featured-panel{margin-top:2em;margin-bottom:2em;background-color:#eaeaea}.featured-panel p:last-child{margin-bottom:0}.pound-gentoo{background-color:#e1e1e1}@media (min-width: 768px){.pound-gentoo{margin-top:1em;margin-bottom:1em}}.ml-actions{width:8em;text-align:right}.huge{font-size:140%}.large{font-size:125%}@media (min-width: 768px){.huge{font-size:200%}.huge h1{font-size:200%}}::selection{background:#dddaec}::-moz-selection{background:#dddaec}.gentoo-nav a:link,.gentoo-nav a:visited{color:#54487a}.old-docs dd{margin-bottom:.5em;margin-left:.5em;font-size:90%}body.nav-align-h2 #content h2:first-of-type{margin-top:0}.caption h3{margin-top:5px}.label-aspect{width:4em;display:inline-block}.gentoo-badges img{max-width:6em;min-width:6em}.herd-desc-col{width:10em}.herd-maint-col{width:50%}@media (min-width: 768px){.frontpage-table{width:100%;table-layout:fixed}.frontpage-table td{text-overflow:ellipsis;max-height:1.2em;overflow:hidden;white-space:nowrap}.frontpage-table-planet-author{width:30%}.frontpage-table-package-atom{width:30%}.frontpage-table-wiki-title{width:70%}}.get-started-icon .fa,.contribute-icon .fa{padding-left:20px}@media (max-width: 768px){.button-bar{line-height:3em}}.site-logo object{overflow:hidden}.use-flag{width:25%}.use-desc{width:75%}.external-link{color:#979797}.stick-top{margin-top:0}.stick-bottom{margin-bottom:0}.logo-table img{max-height:100px}.logo-table td.img{text-align:center}article.newsitem{margin-top:2em}.newsitem-headline{padding-left:45px}.newsitem-content{padding-left:46px}.newsitem-bullet{color:#aaa;float:left}@media (max-width: 768px){.newsitem-bullet{display:none}.newsitem-content,.newsitem-headline{padding-left:0}}.news-img-right{float:right;margin-left:2em}.news-more{text-align:right;margin:0;margin-top:18px;padding:0;font-size:90%}.news-more a:link,.news-more a:active,.news-more a:visited,.news-more a:hover{color:#aaa}.news-more hr{margin-top:2px}.sponsor{margin-bottom:.5em}@media (min-width: 768px){.sponsor{display:flex;align-items:center}}.sponsorlogo{text-align:center}.sponsorlogo img{margin-bottom:.5em}.sponsortext h3{margin-top:0}.text-ad{display:inline-block;height:125px;width:125px;line-height:125px;overflow:hidden;border:1px solid #ddd;padding:2px;font-size:90%;background:#ffffff;background:-moz-linear-gradient(top, #fff 0%, #f6f6f6 47%, #ededed 100%);background:-webkit-gradient(left top, left bottom, color-stop(0%, #fff), color-stop(47%, #f6f6f6), color-stop(100%, #ededed));background:-webkit-linear-gradient(top, #fff 0%, #f6f6f6 47%, #ededed 100%);background:-o-linear-gradient(top, #fff 0%, #f6f6f6 47%, #ededed 100%);background:-ms-linear-gradient(top, #fff 0%, #f6f6f6 47%, #ededed 100%);background:linear-gradient(to bottom, #fff 0%, #f6f6f6 47%, #ededed 100%)}.text-ad>.text-ad-content{display:inline-block;vertical-align:middle;line-height:1.2em}.donate{margin-top:-21px;background-color:#a40000;background-image:url("/assets/img/bg/donate.jpg");cursor:default}.donate-thanks{background-image:url("/assets/img/bg/larry-lessthanthree.png");background-size:contain;background-position:50% 50%;height:400px}.donate h1{color:white;text-shadow:0px 0px 5px black}.donate p{text-shadow:0px 0px 5px black;color:white}@media (min-width: 768px){.donate-form{margin-left:20%;margin-right:20%}}
+
+/*# sourceMappingURL=screen.css.map */
diff --git a/python/bb_dashboard/templates/includes/container/end b/python/bb_dashboard/templates/includes/container/end
new file mode 100644
index 0000000..492b151
--- /dev/null
+++ b/python/bb_dashboard/templates/includes/container/end
@@ -0,0 +1,3 @@
+ </div>
+</div>
+<div class="container"><div class="row"><div class="col-md-12"> \ No newline at end of file
diff --git a/python/bb_dashboard/templates/includes/container/start b/python/bb_dashboard/templates/includes/container/start
new file mode 100644
index 0000000..1dca7a2
--- /dev/null
+++ b/python/bb_dashboard/templates/includes/container/start
@@ -0,0 +1,3 @@
+</div></div></div>
+<div class="hero-section emergehdr">
+ <div class="container">
diff --git a/python/bb_dashboard/templates/includes/layout/footer.html b/python/bb_dashboard/templates/includes/layout/footer.html
new file mode 100644
index 0000000..71d1339
--- /dev/null
+++ b/python/bb_dashboard/templates/includes/layout/footer.html
@@ -0,0 +1,43 @@
+<footer>
+ <div class="container">
+ <div class="row">
+ <div class="col-xs-12 col-md-offset-2 col-md-7">
+ </div>
+ <div class="col-xs-12 col-md-3">
+ <h3 class="footerhead">Questions or comments?</h3>
+ Please feel free to <a href="/inside-gentoo/contact/">contact us</a>.
+ </div>
+ </div>
+ </div>
+ <div class="container">
+ <div class="row">
+ <div class="col-xs-3 col-md-2">
+ <ul class="footerlinks three-icons">
+ <li><a href="https://twitter.com/gentoo" title="@Gentoo on Twitter"><span class="fa fa-twitter fa-fw"></span></a></li>
+ <li><a href="https://www.facebook.com/gentoo.org" title="Gentoo on Facebook"><span class="fa fa-facebook fa-fw"></span></a></li>
+ </ul>
+ <div>
+ <div class="sitemap text-center">
+ <a href="https://wiki.gentoo.org/wiki/Foundation:Privacy_Policy">Privacy Policy</a>
+ </div>
+ </div>
+ </div>
+ <div class="col-xs-8 col-md-8">
+ <strong>&copy; 2001-{% now "Y" %} Gentoo Foundation, Inc.</strong><br>
+ <small>
+ Gentoo is a trademark of the Gentoo Foundation, Inc.
+ The contents of this document, unless otherwise expressly stated, are licensed under the
+ <a href="https://creativecommons.org/licenses/by-sa/3.0/" rel="license">CC-BY-SA-3.0</a> license.
+ The <a href="https://www.gentoo.org/inside-gentoo/foundation/name-logo-guidelines.html">Gentoo Name and Logo Usage Guidelines</a> apply.
+ </small>
+ </div>
+ <div class="col-xs-1 col-md-1">
+ <strong><a class="text-dark" href="https://gitweb.gentoo.org/sites/www.git/">Version</a></strong><br>
+ <small>
+ de76aa4
+
+ </small>
+ </div>
+ </div>
+ </div>
+</footer>
diff --git a/python/bb_dashboard/templates/includes/layout/head.html b/python/bb_dashboard/templates/includes/layout/head.html
new file mode 100644
index 0000000..492b392
--- /dev/null
+++ b/python/bb_dashboard/templates/includes/layout/head.html
@@ -0,0 +1,26 @@
+<head>
+ {% load static %}
+ <title>{% if activemeny.title %}{{ activemeny.title }} – {{ site.title }}{% else %}{{ site.title }}{% endif %}</title>
+ {% if activemeny.description %}<meta name="description" content="{{ activemeny.description }}">{% endif %}
+ <meta charset="utf-8">
+ <meta name="theme-color" content="#54487a">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta property="og:title" content="{% if activemeny.title %}{{ activemeny.title }} – {{ site.title }}{% else %}{{ site.title }}{% endif %}">
+ <meta property="og:image" content="https://www.gentoo.org/assets/img/logo/gentoo-g.png">
+ <meta property="og:description" content="{% if activemeny.description %}{{ activemeny.description }}{% else %}{{ site.description }}{% endif %}">
+ <meta name="twitter:image" content="https://www.gentoo.org/assets/img/logo/gentoo-g.png">
+ <link rel="apple-touch-icon" href="https://www.gentoo.org/assets/img/logo/icon-192.png">
+ <link rel="icon" sizes="192x192" href="https://www.gentoo.org/assets/img/logo/icon-192.png">
+ <link href="https://assets.gentoo.org/tyrian/v1/bootstrap.min.css" rel="stylesheet" media="screen">
+ <link href="https://assets.gentoo.org/tyrian/v1/tyrian.min.css" rel="stylesheet" media="screen">
+ <link href="{% static 'screen.css' %}" rel="stylesheet" media="screen">
+
+ <link rel="icon" href="https://www.gentoo.org/favicon.ico" type="image/x-icon">
+ <link rel="search" type="application/opensearchdescription+xml" href="https://www.gentoo.org/search/www-gentoo-org.xml" title="Gentoo Website">
+ <link rel="search" type="application/opensearchdescription+xml" href="https://www.gentoo.org/search/forums-gentoo-org.xml" title="Gentoo Forums">
+ <link rel="search" type="application/opensearchdescription+xml" href="https://www.gentoo.org/search/bugs-gentoo-org.xml" title="Gentoo Bugzilla">
+ <link rel="search" type="application/opensearchdescription+xml" href="https://www.gentoo.org/search/packages-gentoo-org.xml" title="Gentoo Packages">
+ <link rel="search" type="application/opensearchdescription+xml" href="https://www.gentoo.org/search/archives-gentoo-org.xml" title="Gentoo List Archives">
+ <link rel="alternate" type="application/atom+xml" title="Gentoo Linux news" href="https://www.gentoo.org/feeds/news.xml">
+</head>
diff --git a/python/bb_dashboard/templates/includes/layout/header.html b/python/bb_dashboard/templates/includes/layout/header.html
new file mode 100644
index 0000000..382bcf4
--- /dev/null
+++ b/python/bb_dashboard/templates/includes/layout/header.html
@@ -0,0 +1,89 @@
+<header>
+ <div class="site-title">
+ <div class="container">
+ <div class="row">
+ <div class="site-title-buttons">
+ <div class="btn-group btn-group-sm">
+ <a href="https://get.gentoo.org/" role="button" class="btn get-gentoo"><span class="fa fa-fw fa-download"></span> <strong>Get Gentoo!</strong></a>
+ <div class="btn-group btn-group-sm">
+ <a class="btn gentoo-org-sites dropdown-toggle" data-toggle="dropdown" data-target="#" href="#">
+ <span class="fa fa-fw fa-map-o"></span> <span class="hidden-xs">gentoo.org sites</span> <span class="caret"></span>
+ </a>
+ <ul class="dropdown-menu dropdown-menu-right">
+ <li><a href="https://www.gentoo.org/" title="Main Gentoo website"><span class="fa fa-home fa-fw"></span> gentoo.org</a></li>
+ <li><a href="https://wiki.gentoo.org/" title="Find and contribute documentation"><span class="fa fa-file-text-o fa-fw"></span> Wiki</a></li>
+ <li><a href="https://bugs.gentoo.org/" title="Report issues and find common issues"><span class="fa fa-bug fa-fw"></span> Bugs</a></li>
+ <li><a href="https://forums.gentoo.org/" title="Discuss with the community"><span class="fa fa-comments-o fa-fw"></span> Forums</a></li>
+ <li><a href="https://packages.gentoo.org/" title="Find software for your Gentoo"><span class="fa fa-hdd-o fa-fw"></span> Packages</a></li>
+ <li class="divider"></li>
+ <li><a href="https://planet.gentoo.org/" title="Find out what's going on in the developer community"><span class="fa fa-rss fa-fw"></span> Planet</a></li>
+ <li><a href="https://archives.gentoo.org/" title="Read up on past discussions"><span class="fa fa-archive fa-fw"></span> Archives</a></li>
+ <li><a href="https://gitweb.gentoo.org/" title="Browse our source code in Gitweb"><span class="fa fa-code fa-fw"></span> Gitweb</a></li>
+ <li class="divider"></li>
+ <li><a href="https://infra-status.gentoo.org/" title="Get updates on the services provided by Gentoo"><span class="fa fa-server fa-fw"></span> Infra status</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <div class="logo">
+ <a href="/" title="Back to the homepage" class="site-logo">
+ <object data="https://assets.gentoo.org/tyrian/site-logo.svg" type="image/svg+xml">
+ <img src="https://assets.gentoo.org/tyrian/site-logo.png" alt="Gentoo Linux logo">
+ </object>
+ </a>
+ <span class="site-label">Gentoo Ci Dashboard</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ <nav class="tyrian-navbar" role="navigation">
+ <div class="container">
+ <div class="row">
+ <div class="navbar-header">
+ <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-main-collapse">
+ <span class="sr-only">Toggle navigation</span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </button>
+ </div>
+ <div class="collapse navbar-collapse navbar-main-collapse">
+ <ul class="nav navbar-nav">
+ {% include "includes/navigation/primary" %}
+ </ul>
+ <ul class="nav navbar-nav navbar-right">
+ <li class=""><a href="http://www.gentoo.org/donate/"><span class="fa fa-heart" style="color:#d9534f;"></span> Donate</a></li>
+ </ul>
+ <ul class="nav navbar-nav navbar-right">
+ <li class=""><span class="" style="color:#d9534f;"></span>
+ {% if user.is_authenticated %}
+ Welcome, {{ user.username }}. Thanks for logging in.
+ {% endif %}
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </nav>
+ {% if subpages %}
+ <nav class="navbar navbar-grey navbar-stick" role="navigation">
+ <div class="container">
+ <div class="row">
+ <div class="navbar-header">
+ <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-secondary-collapse">
+ <span class="sr-only">Toggle secondary navigation</span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </button>
+ </div>
+ <div class="collapse navbar-collapse navbar-secondary-collapse">
+ <ul class="nav navbar-nav">
+ {% include "includes/navigation/secondary" %}
+ </ul>
+ </div>
+ </div>
+ </div>
+ </nav>
+ {% endif %}
+</header>
diff --git a/python/bb_dashboard/templates/includes/navigation/primary b/python/bb_dashboard/templates/includes/navigation/primary
new file mode 100644
index 0000000..9db245d
--- /dev/null
+++ b/python/bb_dashboard/templates/includes/navigation/primary
@@ -0,0 +1,10 @@
+{% for meny in menys %}
+ {% if meny.view %}
+ {% if activemeny.name == meny.name %}
+ <li class="active">
+ {% else %}
+ <li class="">
+ {% endif %}
+ <a href="/{{ meny.url }}/">{{meny.title}}</a></li>
+ {% endif %}
+{% endfor %}
diff --git a/python/bb_dashboard/templates/includes/navigation/secondary b/python/bb_dashboard/templates/includes/navigation/secondary
new file mode 100644
index 0000000..ad11ad5
--- /dev/null
+++ b/python/bb_dashboard/templates/includes/navigation/secondary
@@ -0,0 +1,10 @@
+{% for meny in submenys %}
+ {% if meny.view %}
+ {% if subactivemeny == meny.name %}
+ <li class="active">
+ {% else %}
+ <li class="">
+ {% endif %}
+ <a href="{% url meny.url %}">{{meny.title}}</a></li>
+ {% endif %}
+{% endfor %}
diff --git a/python/bb_dashboard/templates/layout/base.html b/python/bb_dashboard/templates/layout/base.html
new file mode 100644
index 0000000..0dd7d8c
--- /dev/null
+++ b/python/bb_dashboard/templates/layout/base.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+ {% include "includes/layout/head.html" %}
+ <body class="">
+ {% include "includes/layout/header.html" %}
+
+ <div class="container">
+ <div class="row">
+ <div id="content" class="col-md-12">
+ {% block content %}{% endblock %}
+ </div>
+ </div>
+ </div>
+
+ {% include "includes/layout/footer.html" %}
+
+ <script src="https://assets.gentoo.org/tyrian/v1/jquery.min.js"></script>
+ <script src="https://assets.gentoo.org/tyrian/v1/bootstrap.min.js"></script>
+ </body>
+</html>
diff --git a/python/bb_dashboard/www/__init__.py b/python/bb_dashboard/www/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/python/bb_dashboard/www/__init__.py
diff --git a/python/bb_dashboard/www/admin.py b/python/bb_dashboard/www/admin.py
new file mode 100644
index 0000000..168b0b2
--- /dev/null
+++ b/python/bb_dashboard/www/admin.py
@@ -0,0 +1,7 @@
+from django.contrib import admin
+
+from .models import SiteSettings, Menys, SubMenys
+
+admin.site.register(SiteSettings)
+admin.site.register(Menys)
+admin.site.register(SubMenys)
diff --git a/python/bb_dashboard/www/apps.py b/python/bb_dashboard/www/apps.py
new file mode 100644
index 0000000..a339bca
--- /dev/null
+++ b/python/bb_dashboard/www/apps.py
@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class WwwConfig(AppConfig):
+ default_auto_field = 'django.db.models.BigAutoField'
+ name = 'www'
diff --git a/python/bb_dashboard/www/migrations/0001_initial.py b/python/bb_dashboard/www/migrations/0001_initial.py
new file mode 100644
index 0000000..d2ef79d
--- /dev/null
+++ b/python/bb_dashboard/www/migrations/0001_initial.py
@@ -0,0 +1,95 @@
+# Generated by Django 3.2.3 on 2021-06-12 23:07
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Menys',
+ fields=[
+ ('id', models.IntegerField(primary_key=True, serialize=False)),
+ ('title', models.CharField(max_length=200)),
+ ('description', models.CharField(max_length=200)),
+ ('name', models.CharField(max_length=100)),
+ ('view', models.BooleanField(default=False)),
+ ('sort', models.IntegerField(default=0)),
+ ('url', models.CharField(max_length=200)),
+ ('arg', models.CharField(blank=True, max_length=50)),
+ ('access', models.BooleanField(default=False)),
+ ('sub', models.BooleanField(default=False)),
+ ],
+ options={
+ 'db_table': 'menys',
+ },
+ ),
+ migrations.CreateModel(
+ name='Posts',
+ fields=[
+ ('id', models.IntegerField(primary_key=True, serialize=False)),
+ ('title', models.CharField(max_length=200)),
+ ('url', models.CharField(max_length=200)),
+ ('text', models.TextField()),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ],
+ options={
+ 'db_table': 'posts',
+ },
+ ),
+ migrations.CreateModel(
+ name='SiteSettings',
+ fields=[
+ ('id', models.IntegerField(primary_key=True, serialize=False)),
+ ('site', models.CharField(max_length=20)),
+ ('title', models.CharField(max_length=50)),
+ ('email', models.CharField(max_length=50)),
+ ('description', models.CharField(max_length=100)),
+ ('url', models.CharField(max_length=50)),
+ ('contact', models.CharField(max_length=50)),
+ ],
+ options={
+ 'db_table': 'site_settings',
+ },
+ ),
+ migrations.CreateModel(
+ name='Sponsors',
+ fields=[
+ ('id', models.IntegerField(primary_key=True, serialize=False)),
+ ('name', models.CharField(max_length=200)),
+ ('img', models.CharField(max_length=200)),
+ ('link', models.CharField(max_length=200)),
+ ('title', models.CharField(max_length=200)),
+ ('alt', models.CharField(max_length=200)),
+ ('weight', models.IntegerField(default=0)),
+ ('active', models.BooleanField(default=False)),
+ ],
+ options={
+ 'db_table': 'sponsors',
+ },
+ ),
+ migrations.CreateModel(
+ name='SubMenys',
+ fields=[
+ ('id', models.IntegerField(primary_key=True, serialize=False)),
+ ('title', models.CharField(max_length=200)),
+ ('description', models.CharField(max_length=200)),
+ ('name', models.CharField(max_length=100)),
+ ('view', models.BooleanField(default=False)),
+ ('sort', models.IntegerField(default=0)),
+ ('url', models.CharField(max_length=200)),
+ ('arg', models.CharField(blank=True, max_length=50)),
+ ('access', models.BooleanField(default=False)),
+ ('MenyId', models.ForeignKey(db_column='meny_id', on_delete=django.db.models.deletion.CASCADE, to='www.menys')),
+ ],
+ options={
+ 'db_table': 'sub_menys',
+ },
+ ),
+ ]
diff --git a/python/bb_dashboard/www/migrations/__init__.py b/python/bb_dashboard/www/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/python/bb_dashboard/www/migrations/__init__.py
diff --git a/python/bb_dashboard/www/models.py b/python/bb_dashboard/www/models.py
new file mode 100644
index 0000000..85dbc35
--- /dev/null
+++ b/python/bb_dashboard/www/models.py
@@ -0,0 +1,74 @@
+# Copyright 1998-2019 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from django.db import models
+
+class SiteSettings(models.Model):
+ id = models.IntegerField(primary_key=True)
+ site = models.CharField(max_length=20)
+ title = models.CharField(max_length=50)
+ email = models.CharField(max_length=50)
+ description = models.CharField(max_length=100)
+ url = models.CharField(max_length=50)
+ contact = models.CharField(max_length=50)
+ class Meta:
+ db_table = 'site_settings'
+ def __str__(self):
+ return '%s %s %s %s %s %s %s' % (self.id, self.site, self.title, self.email, self.description, self.url, self.contact)
+
+class Menys(models.Model):
+ id = models.IntegerField(primary_key=True)
+ title = models.CharField(max_length=200)
+ description = models.CharField(max_length=200)
+ name = models.CharField(max_length=100)
+ view = models.BooleanField(default=False)
+ sort = models.IntegerField(default=0)
+ url = models.CharField(max_length=200)
+ arg = models.CharField(max_length=50, blank=True)
+ access = models.BooleanField(default=False)
+ sub = models.BooleanField(default=False)
+ class Meta:
+ db_table = 'menys'
+ def __str__(self):
+ return '%s %s %s %s %s %s %s %s %s %s' % (self.id, self.title, self.description, self.name, self.view, self.sort, self.url, self.arg, self.access, self.sub)
+
+class SubMenys(models.Model):
+ id = models.IntegerField(primary_key=True)
+ title = models.CharField(max_length=200)
+ description = models.CharField(max_length=200)
+ MenyId = models.ForeignKey(Menys, on_delete=models.CASCADE, db_column='meny_id')
+ name = models.CharField(max_length=100)
+ view = models.BooleanField(default=False)
+ sort = models.IntegerField(default=0)
+ url = models.CharField(max_length=200)
+ arg = models.CharField(max_length=50, blank=True)
+ access = models.BooleanField(default=False)
+ class Meta:
+ db_table = 'sub_menys'
+ def __str__(self):
+ return '%s %s %s %s %s %s %s %s %s %s' % (self.id, self.title, self.description, self.MenyId, self.name, self.view, self.sort, self.url, self.arg, self.access)
+
+class Posts(models.Model):
+ id = models.IntegerField(primary_key=True)
+ title = models.CharField(max_length=200)
+ url = models.CharField(max_length=200)
+ text = models.TextField()
+ created_at = models.DateTimeField(auto_now_add=True)
+ class Meta:
+ db_table='posts'
+ def __str__(self):
+ return '%s %s %s %s %s' % (self.id, self.title, self.url, self.text, self.created_at)
+
+class Sponsors(models.Model):
+ id = models.IntegerField(primary_key=True)
+ name = models.CharField(max_length=200)
+ img = models.CharField(max_length=200)
+ link = models.CharField(max_length=200)
+ title = models.CharField(max_length=200)
+ alt = models.CharField(max_length=200)
+ weight = models.IntegerField(default=0)
+ active = models.BooleanField(default=False)
+ class Meta:
+ db_table = 'sponsors'
+ def __str__(self):
+ return '%s %s %s %s %s %s %s' % (self.id, self.name, self.img, self.link, self.alt, self.weight, self.active)
diff --git a/python/bb_dashboard/www/router.py b/python/bb_dashboard/www/router.py
new file mode 100644
index 0000000..70fa685
--- /dev/null
+++ b/python/bb_dashboard/www/router.py
@@ -0,0 +1,31 @@
+# Copyright 1998-2015 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+class WWWRouter(object):
+ def db_for_read(self, model, **hints):
+ "Point all operations on zobcs models to 'zobcs'"
+ if model._meta.app_label == 'www':
+ return 'default'
+ return 'gentoo-ci'
+
+ def db_for_write(self, model, **hints):
+ "Point all operations on zobcs models to 'zobcs'"
+ if model._meta.app_label == 'www':
+ return 'default'
+ return 'gentoo-ci'
+
+ def allow_relation(self, obj1, obj2, **hints):
+ "Allow any relation if a both models in zobcs app"
+ if obj1._meta.app_label == 'www' and obj2._meta.app_label == 'www':
+ return True
+ # Allow if neither is zobcs app
+ elif 'www' not in [obj1._meta.app_label, obj2._meta.app_label]:
+ return True
+ return False
+
+ def allow_migrate(self, db, app_label, model_name=None, **hints):
+ if db == 'gentoo-ci':
+ return app_label == 'gentoo-ci'
+ elif app_label == 'gentoo-ci':
+ return False
+ return True
diff --git a/python/bb_dashboard/www/templates/www/index.html b/python/bb_dashboard/www/templates/www/index.html
new file mode 100644
index 0000000..18ecc63
--- /dev/null
+++ b/python/bb_dashboard/www/templates/www/index.html
@@ -0,0 +1,42 @@
+{% extends "layout/base.html" %}
+{% block content %}
+{% include "includes/container/start" %}
+<div class="row">
+ <div class="col-xs-12 col-sm-8 col-md-9">
+ <p>
+ Welcome to Gentoo Ci Dashboard.
+ </p>
+ </div>
+ <div class="col-xs-12 col-sm-4 col-md-3 buttons">
+ <a href="/get-started/about/" class="btn btn-default btn-block">Learn more</a>
+ <a href="/get-started/" class="btn btn-primary btn-block"><i class="fa fa-fw fa-rocket"></i> Get started now</a>
+ </div>
+</div>
+{% include "includes/container/end" %}
+{% include "www/news.html" %}
+
+<div class="row">
+ <div class="col-xs-12 col-md-6">
+ <h2>New Commits <small>more at the <a href="/new_packages/">New Commits</a></small></h2>
+
+ </div>
+ <div class="col-xs-12 col-md-6">
+ <h2>New Builds <small>more at the <a href="/new_logs/">New Builds</a></small></h2>
+
+ </div>
+</div>
+
+<div class="row">
+ <div class="col-xs-12 col-md-6">
+ <h2>New Build Requests <small>more at the <a href="/new_build_req">New Build Requests</a></small></h2>
+
+ </div>
+ <div class="col-xs-12 col-md-6">
+ <h2>New Pkgcheck or QA checks <small>on the <a href="/new/repomanqa/">New Pkgcheck or QA checks</a></small></h2>
+
+ </div>
+</div>
+
+<hr>
+
+{% endblock %}
diff --git a/python/bb_dashboard/www/templates/www/news.html b/python/bb_dashboard/www/templates/www/news.html
new file mode 100644
index 0000000..b722f51
--- /dev/null
+++ b/python/bb_dashboard/www/templates/www/news.html
@@ -0,0 +1,20 @@
+<section id="news">
+{% for post in posts %}
+<article class="newsitem">
+<h2 class="stick-top newsitem-bullet">
+ <span class="fa fa-fw fa-chevron-circle-right" title="News item"> </span>
+ </h2>
+ <h2 class="stick-top newsitem-headline">
+ <a href="{{ post.url }}">{{ post.title }}</a> <small>{{ post.created_at }}</small>
+ </h2>
+ <div class="newsitem-content">
+ <p>{{ post.text|safe|escape }}</p>
+ </div>
+</article>
+{% endfor %}
+</section>
+
+<div class="news-more">
+ <a href="/news" class="btn btn-xs">All news items <span class="fa fa-fw fa-chevron-right"></span></a>
+<hr>
+</div>
diff --git a/python/bb_dashboard/www/tests.py b/python/bb_dashboard/www/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/python/bb_dashboard/www/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/python/bb_dashboard/www/urls.py b/python/bb_dashboard/www/urls.py
new file mode 100644
index 0000000..88a9cac
--- /dev/null
+++ b/python/bb_dashboard/www/urls.py
@@ -0,0 +1,7 @@
+from django.urls import path
+
+from . import views
+
+urlpatterns = [
+ path('', views.index, name='index'),
+]
diff --git a/python/bb_dashboard/www/utils.py b/python/bb_dashboard/www/utils.py
new file mode 100644
index 0000000..a69f406
--- /dev/null
+++ b/python/bb_dashboard/www/utils.py
@@ -0,0 +1,55 @@
+# Copyright 1998-2019 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import calendar
+import datetime
+import dateutil.tz
+
+from django.shortcuts import get_object_or_404
+from www.models import SiteSettings, Menys, SubMenys
+
+def default_siteinfo(request, menyrequest):
+ siteinfo = {}
+ siteinfo['site'] = get_object_or_404(SiteSettings)
+ activemeny = get_object_or_404(Menys, name = menyrequest)
+ menys = Menys.objects.all().order_by('sort')
+ #contact = get_object_or_404(SubPages, nav2 = 'contact')
+ for meny in menys:
+ if meny.title == 'Login' and request.user.is_authenticated:
+ meny.show = False
+ if meny.title == 'User' and request.user.is_authenticated:
+ meny.show = True
+ if meny.arg == '':
+ meny.arg = False
+ siteinfo['activemeny'] = activemeny
+ siteinfo['menys'] = menys
+ #siteinfo['contact'] = contact
+ if activemeny.sub:
+ submenys = SubMenys.objects.filter(MenyId = activemeny.id).order_by('sort')
+ for submeny in submenys:
+ if submeny.arg == '':
+ submeny.arg = False
+ siteinfo['submenys'] = submenys
+ siteinfo['subactivemeny'] = False
+ else:
+ siteinfo['submenys'] = []
+ siteinfo['subactivemeny'] = False
+ return siteinfo
+
+# time-handling methods
+
+# this used to be a custom class; now it's just an instance of dateutil's class
+UTC = dateutil.tz.tzutc()
+
+def epoch2datetime(epoch):
+ """Convert a UNIX epoch time to a datetime object, in the UTC timezone"""
+ if epoch is not None:
+ return datetime.datetime.fromtimestamp(epoch, tz=UTC)
+ return None
+
+
+def datetime2epoch(dt):
+ """Convert a non-naive datetime object to a UNIX epoch timestamp"""
+ if dt is not None:
+ return calendar.timegm(dt.utctimetuple())
+ return None
diff --git a/python/bb_dashboard/www/views.py b/python/bb_dashboard/www/views.py
new file mode 100644
index 0000000..05dcd10
--- /dev/null
+++ b/python/bb_dashboard/www/views.py
@@ -0,0 +1,16 @@
+# Copyright 1998-2019 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from django.http import HttpResponse
+from django.shortcuts import render
+from django.conf import settings
+
+from .utils import default_siteinfo
+from .models import Posts
+
+def index(request):
+ menyrequest = 'www'
+ siteinfo = default_siteinfo(request, menyrequest)
+ siteinfo['posts'] = Posts.objects.all()[:2]
+ htmlrequest = menyrequest + '/index.html'
+ return render(request, htmlrequest, siteinfo)