commit:     3fb5065d4b67af1df11cec4e7a3e888c9598b9d1
Author:     Magnus Granberg <zorry <AT> gentoo <DOT> org>
AuthorDate: Fri Sep 24 01:54:59 2021 +0000
Commit:     Magnus Granberg <zorry <AT> gentoo <DOT> org>
CommitDate: Fri Sep 24 02:22:49 2021 +0000
URL:        
https://gitweb.gentoo.org/proj/tinderbox-cluster-www.git/commit/?id=3fb5065d

Add Buildbot Dashboard for Gentoo Ci

Signed-off-by: Magnus Granberg <zorry <AT> gentoo.org>

 .gitignore                                         |   5 +
 python/bb_dashboard/bb_dashboard/__init__.py       |   0
 python/bb_dashboard/bb_dashboard/asgi.py           |  16 +++
 .../bb_dashboard/bb_dashboard/settings.py.sample   | 149 +++++++++++++++++++++
 python/bb_dashboard/bb_dashboard/urls.py           |   9 ++
 python/bb_dashboard/bb_dashboard/wsgi.py           |  16 +++
 python/bb_dashboard/manage.py                      |  22 +++
 python/bb_dashboard/projects/__init__.py           |   0
 python/bb_dashboard/projects/admin.py              |   3 +
 python/bb_dashboard/projects/apps.py               |   6 +
 .../bb_dashboard/projects/migrations/__init__.py   |   0
 python/bb_dashboard/projects/models.py             |   3 +
 python/bb_dashboard/projects/tests.py              |   3 +
 python/bb_dashboard/projects/views.py              |   3 +
 python/bb_dashboard/repository/__init__.py         |   0
 python/bb_dashboard/repository/admin.py            |   3 +
 python/bb_dashboard/repository/apps.py             |   6 +
 .../bb_dashboard/repository/migrations/__init__.py |   0
 python/bb_dashboard/repository/models.py           |  45 +++++++
 python/bb_dashboard/repository/tests.py            |   3 +
 python/bb_dashboard/repository/views.py            |   3 +
 python/bb_dashboard/static/screen.css              |   3 +
 .../templates/includes/container/end               |   0
 .../templates/includes/container/start             |   3 +
 .../templates/includes/layout/footer.html          |  43 ++++++
 .../templates/includes/layout/head.html            |  26 ++++
 .../templates/includes/layout/header.html          |  89 ++++++++++++
 .../templates/includes/navigation/primary          |   0
 .../templates/includes/navigation/secondary        |   0
 python/bb_dashboard/templates/layout/base.html     |  20 +++
 python/bb_dashboard/www/__init__.py                |   0
 python/bb_dashboard/www/admin.py                   |   7 +
 python/bb_dashboard/www/apps.py                    |   6 +
 python/bb_dashboard/www/migrations/0001_initial.py |  95 +++++++++++++
 python/bb_dashboard/www/migrations/__init__.py     |   0
 python/bb_dashboard/www/models.py                  |  74 ++++++++++
 python/bb_dashboard/www/router.py                  |  31 +++++
 python/bb_dashboard/www/templates/www/index.html   |  42 ++++++
 .../www/templates/www/news.html}                   |   9 +-
 python/bb_dashboard/www/tests.py                   |   3 +
 python/bb_dashboard/www/urls.py                    |   7 +
 python/bb_dashboard/www/utils.py                   |  55 ++++++++
 python/bb_dashboard/www/views.py                   |  16 +++
 python/templates/includes/container/start          |   3 -
 python/templates/includes/frontpage/new_build_req  |  15 ---
 python/templates/includes/frontpage/new_logs       |  27 ----
 python/templates/includes/frontpage/new_packages   |  10 --
 python/templates/includes/frontpage/new_repoman_qa |  18 ---
 .../includes/navigation/sitemap_secondary          |   5 -
 49 files changed, 823 insertions(+), 79 deletions(-)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ddf3b02
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+# Backup files
+*~
+__pycache__
+python/bb_dashboard/bb_dashboard/settings.py
+

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

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

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

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

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

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}.gento
 o-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{floa
 
t: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:l
 inear-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/templates/includes/container/end 
b/python/bb_dashboard/templates/includes/container/end
similarity index 100%
rename from python/templates/includes/container/end
rename to python/bb_dashboard/templates/includes/container/end

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/templates/includes/navigation/primary 
b/python/bb_dashboard/templates/includes/navigation/primary
similarity index 100%
rename from python/templates/includes/navigation/primary
rename to python/bb_dashboard/templates/includes/navigation/primary

diff --git a/python/templates/includes/navigation/secondary 
b/python/bb_dashboard/templates/includes/navigation/secondary
similarity index 100%
rename from python/templates/includes/navigation/secondary
rename to python/bb_dashboard/templates/includes/navigation/secondary

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

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

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/templates/includes/frontpage/news 
b/python/bb_dashboard/www/templates/www/news.html
similarity index 66%
rename from python/templates/includes/frontpage/news
rename to python/bb_dashboard/www/templates/www/news.html
index 1f1a7d3..b722f51 100644
--- a/python/templates/includes/frontpage/news
+++ b/python/bb_dashboard/www/templates/www/news.html
@@ -1,5 +1,6 @@
+<section id="news">
 {% for post in posts %}
-<article>
+<article class="newsitem">
 <h2 class="stick-top newsitem-bullet">
       <span class="fa fa-fw fa-chevron-circle-right" title="News item"> </span>
     </h2>
@@ -11,3 +12,9 @@
    </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)

diff --git a/python/templates/includes/container/start 
b/python/templates/includes/container/start
deleted file mode 100644
index 2ec1951..0000000
--- a/python/templates/includes/container/start
+++ /dev/null
@@ -1,3 +0,0 @@
-</div></div></div>
-<div class="{{ class_include }}">
-  <div class="container">
\ No newline at end of file

diff --git a/python/templates/includes/frontpage/new_build_req 
b/python/templates/includes/frontpage/new_build_req
deleted file mode 100644
index 3a47530..0000000
--- a/python/templates/includes/frontpage/new_build_req
+++ /dev/null
@@ -1,15 +0,0 @@
-<table class="table table-striped frontpage-table">
-  {% for k, v in BJ.items %}
-    <tr>
-      <td class="frontpage-table-package-atom"><a href="/new_build_req/{{ k 
}}" title="{{ v.C }}/{{ v.P }}-{{ v.V }}::{{ v.R }}">{{ v.C }}/{{ v.P }}-{{ v.V 
}}::{{ v.R }}</a></td>
-      <td><p title="{{ v.title }}">{{ v.title|truncatewords:2}}</p>
-      <td class="text-right">
-      {% if v.Status == 'Building' %}
-        <span class="label label-primary">{{ v.Status }}</span>
-      {% else %}
-        <span class="label label-default">{{ v.Status }}</span>
-      {% endif %}
-      </td></td>
-    </tr>
-  {% endfor %}
-</table>
\ No newline at end of file

diff --git a/python/templates/includes/frontpage/new_logs 
b/python/templates/includes/frontpage/new_logs
deleted file mode 100644
index 3074c4d..0000000
--- a/python/templates/includes/frontpage/new_logs
+++ /dev/null
@@ -1,27 +0,0 @@
-<table class="table table-striped frontpage-table">
-  {% for B in BL%}
-    <tr>
-      <td class="frontpage-table-package-atom"><a href="/new_logs/{{ 
B.BuildLogId }}/" title="{{ B.C }}/{{ B.P }}-{{ B.V }}::{{ B.R }}">
-      {{ B.C }}/{{ B.P }}-{{ B.V }}::{{ B.R }}</a></td>
-      <td><p title="{{ B.SummeryText }}">{{ B.SummeryText|truncatewords:3 
}}</p>
-      <td class="text-right">
-        {% if B.Fail %}
-          {% for BE in B.BE_tmp %}
-            {% if BE.BuildLogId.BuildLogId == B.BuildLogId %}
-              {% if BE.ErrorId.ErrorId == 1 or BE.ErrorId.ErrorId == 2 %}
-                <span class="label label-warning">{{ 
BE.ErrorId.ErrorName|upper }}</span>
-              {% elif BE.ErrorId.ErrorId == 3 %}
-                <span class="label label-info">OTHERS</span>
-              {% else %}
-                <span class="label label-danger">{{ BE.ErrorId.ErrorName|upper 
}}</span>
-              {% endif %}
-            {% endif %}
-          {% endfor %}
-        {% else %}
-          <span class="label label-success">OK</span>
-        {% endif %}
-      </td>
-      </td>
-    </tr>
-  {% endfor %}
-</table>
\ No newline at end of file

diff --git a/python/templates/includes/frontpage/new_packages 
b/python/templates/includes/frontpage/new_packages
deleted file mode 100644
index 6c845b7..0000000
--- a/python/templates/includes/frontpage/new_packages
+++ /dev/null
@@ -1,10 +0,0 @@
-<table class="table table-striped frontpage-table">
-  {% for E in EM %}
-    <tr>
-      <td class="frontpage-table-package-atom">
-          <a href="/packages/{{ E.EbuildId.PackageId.PackageId }}/" title="{{ 
E.EbuildId.PackageId.CategoryId.Category }}/{{ E.EbuildId.PackageId.Package 
}}-{{ E.EbuildId.Version }}::{{ E.EbuildId.PackageId.RepoId.Repo }}">
-          {{ E.EbuildId.PackageId.CategoryId.Category }}/{{ 
E.EbuildId.PackageId.Package }}-{{ E.EbuildId.Version }}::{{ 
E.EbuildId.PackageId.RepoId.Repo }}</a></td>
-        <td><p title="{{ E.Descriptions }}">{{ E.Descriptions }}</p></td>
-    </tr>
-  {% endfor %}
-</table>
\ No newline at end of file

diff --git a/python/templates/includes/frontpage/new_repoman_qa 
b/python/templates/includes/frontpage/new_repoman_qa
deleted file mode 100644
index 61ac691..0000000
--- a/python/templates/includes/frontpage/new_repoman_qa
+++ /dev/null
@@ -1,18 +0,0 @@
-<table class="table table-striped frontpage-table">
-  {% for QA in QA_tmp %}
-    <tr>
-      <td class="frontpage-table-package-atom"><a href="/repoman_qa/{{ 
QA.BuildLogId.BuildLogId }}/"  title="{{ 
QA.BuildLogId.EbuildId.PackageId.CategoryId.Category }}/{{ 
QA.BuildLogId.EbuildId.PackageId.Package }}-{{ QA.BuildLogId.EbuildId.Version 
}}::{{ QA.BuildLogId.EbuildId.PackageId.RepoId.Repo }}">
-      {{ QA.BuildLogId.EbuildId.PackageId.CategoryId.Category }}/{{ 
QA.BuildLogId.EbuildId.PackageId.Package }}-{{ QA.BuildLogId.EbuildId.Version 
}}::{{ QA.BuildLogId.EbuildId.PackageId.RepoId.Repo }}</a>
-      </td>
-      <td><p title="{{ QA.SummeryText }}">{{ QA.SummeryText|truncatewords:3 
}}</p></td>
-    </tr>
-  {% endfor %}
-  {% for PR in PR_tmp %}
-    <tr>
-      <td class="frontpage-table-package-atom"><a href="/repoman/{{ 
PR.PackageId.PackageId }}/"  title="{{ PR.PackageId.CategoryId.Category }}/{{ 
PR.PackageId.Package }}::{{ PR.PackageId.RepoId.Repo }}">
-      {{ PR.PackageId.CategoryId.Category }}/{{ PR.PackageId.Package }}::{{ 
PR.PackageId.RepoId.Repo }}</a>
-      </td>
-      <td><p title="{{ PR.RepomanText }}">{{ PR.RepomanText|truncatewords:3 
}}</p></td>
-    </tr>
-  {% endfor %}
-</table>
\ No newline at end of file

diff --git a/python/templates/includes/navigation/sitemap_secondary 
b/python/templates/includes/navigation/sitemap_secondary
deleted file mode 100644
index f7b5379..0000000
--- a/python/templates/includes/navigation/sitemap_secondary
+++ /dev/null
@@ -1,5 +0,0 @@
-{% for node in smappages %}
-  {% if page.PageId == node.PageId.PageId %}
-    <li><a href="{{node.url }}">{% if node.nav_title %}{{ node.nav_title }}{% 
else %}{{node.title}}{% endif %}</a></li>
-  {% endif %}
-{% endfor %}

Reply via email to