Compare commits

...
This repository has been archived on 2024-07-30. You can view files and clone it, but cannot push or open issues or pull requests.

19 Commits

Author SHA1 Message Date
teras
58a90fe761 Fixed challenges not having an description 2018-01-31 18:27:35 +02:00
teras
9dec2d6e3a Fixed some front-end visuals 2018-01-31 17:52:23 +02:00
teras
02157c7582 Server changes 2018-01-31 16:44:00 +02:00
4316c33533 Add core team members list and services 2017-12-03 16:51:21 +02:00
teras
c775376419 Challenges now connected to items and added items hidden field 2017-12-03 15:46:54 +02:00
2f510f32e1 Separate map and correct room usage 2017-12-03 14:26:15 +02:00
teras
aff3c50e70 Added argument to inventory item picture function 2017-12-02 22:37:57 +02:00
teras
305ff7b192 Added inventory view and challenge blurb + recurring field 2017-12-02 22:26:04 +02:00
teras
2eb090d16c Removed dead code 2017-12-02 21:46:40 +02:00
teras
f58a4dc05f Added markdown description for challenges and profile info 2017-12-02 21:24:54 +02:00
teras
4814beb40d Changed some cascades to null and removed inventory item item code 2017-12-02 19:46:53 +02:00
teras
f16ae12e7e Added InventoryItemOwner and changed InventoryItem field orders 2017-12-02 19:13:41 +02:00
teras
2f10091592 Lauri's temporary logo 2017-12-02 18:25:25 +02:00
teras
4c27f74099 on_delete for foreign keys for SQL 2017-12-02 18:03:37 +02:00
teras
d0fac6602f Automatic challenge creator user 2017-12-02 17:49:35 +02:00
teras
c70e85342a InventoryItem and InventoryItemLocation models 2017-12-01 21:14:06 +02:00
teras
91c0b509ef Changed project name 2017-11-16 15:13:29 +02:00
teras
7073d76afd Added required files 2017-10-17 11:10:30 +03:00
teras
fe4931a8b4 Removed PyCharm files 2017-10-11 14:14:11 +03:00
38 changed files with 1017 additions and 413 deletions

14
.gitignore vendored
View File

@ -101,9 +101,19 @@ ENV/
.mypy_cache/ .mypy_cache/
db.sqlite3 db.sqlite3
workspace.xml
tasks.xml tasks.xml
media/icons media/icons
challenges/migrations media/inventory
*/migrations
static/ static/
#PyCharm files
.idea/deployment.xml
.idea/misc.xml
.idea/modules.xml
.idea/vcs.xml
.idea/workspace.xml
db.conf

1
.idea/.name Normal file
View File

@ -0,0 +1 @@
kspace

View File

@ -4,8 +4,14 @@
<option name="PER_PROJECT_SETTINGS"> <option name="PER_PROJECT_SETTINGS">
<value> <value>
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" /> <option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<codeStyleSettings language="HTML">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
</value> </value>
</option> </option>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" /> <option name="USE_PER_PROJECT_SETTINGS" value="true" />
</component> </component>
</project> </project>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="dataSourceStorageLocal">
<data-source name="Django default" uuid="810b5a68-e40c-47b5-b764-41dab6eceb8f">
<database-info product="" version="" jdbc-version="" driver-name="" driver-version="" />
<auth-required>false</auth-required>
<first-sync>true</first-sync>
</data-source>
</component>
</project>

16
.idea/dataSources.xml Normal file
View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="Django default" uuid="810b5a68-e40c-47b5-b764-41dab6eceb8f">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<imported>true</imported>
<remarks>$PROJECT_DIR$/kspace/settings.py</remarks>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/db.sqlite3</jdbc-url>
<driver-properties>
<property name="enable_load_extension" value="true" />
</driver-properties>
</data-source>
</component>
</project>

View File

@ -0,0 +1,20 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="PyCompatibilityInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ourVersions">
<value>
<list size="2">
<item index="0" class="java.lang.String" itemvalue="2.7" />
<item index="1" class="java.lang.String" itemvalue="3.6" />
</list>
</value>
</option>
</inspection_tool>
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<option name="processCode" value="true" />
<option name="processLiterals" value="true" />
<option name="processComments" value="true" />
</inspection_tool>
</profile>
</component>

View File

@ -3,8 +3,8 @@
<component name="FacetManager"> <component name="FacetManager">
<facet type="django" name="Django"> <facet type="django" name="Django">
<configuration> <configuration>
<option name="rootFolder" value="$MODULE_DIR$" /> <option name="rootFolder" value="$MODULE_DIR$/kspace" />
<option name="settingsModule" value="challenges/settings.py" /> <option name="settingsModule" value="settings.py" />
<option name="manageScript" value="$MODULE_DIR$/manage.py" /> <option name="manageScript" value="$MODULE_DIR$/manage.py" />
<option name="environment" value="&lt;map/&gt;" /> <option name="environment" value="&lt;map/&gt;" />
</configuration> </configuration>
@ -19,7 +19,7 @@
<option name="TEMPLATE_CONFIGURATION" value="Django" /> <option name="TEMPLATE_CONFIGURATION" value="Django" />
<option name="TEMPLATE_FOLDERS"> <option name="TEMPLATE_FOLDERS">
<list> <list>
<option value="$MODULE_DIR$/templates" /> <option value="$MODULE_DIR$/../k-space/templates" />
</list> </list>
</option> </option>
</component> </component>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.5.3 (/usr/bin/python3.5)" project-jdk-type="Python SDK" />
</project>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/challenges.iml" filepath="$PROJECT_DIR$/.idea/challenges.iml" />
</modules>
</component>
</project>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

15
.idea/webServers.xml Normal file
View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WebServers">
<option name="servers">
<webServer id="9c59bcc8-a0ad-496c-a272-db66d8c32068" name="K-Space" url="http://kspace.ee">
<fileTransfer host="kspace.ee" port="22" rootFolder="/root" accessType="SFTP" authAgent="true">
<advancedOptions>
<advancedOptions dataProtectionLevel="Private" />
</advancedOptions>
<option name="port" value="22" />
</fileTransfer>
</webServer>
</option>
</component>
</project>

View File

@ -1,7 +0,0 @@
from django.contrib import admin
from challenges.models import *
admin.site.register(Challenge)
admin.site.register(ChallengeTag)
admin.site.register(UserChallenge)
admin.site.register(Profile)

View File

@ -1,54 +0,0 @@
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
import os
def get_image_path(instance, filename):
return os.path.join('icons', str(instance.id), filename)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
icon = models.ImageField(upload_to=get_image_path, default='default_icon.png')
def __str__(self):
return self.user.username
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
class ChallengeTag(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
description = models.TextField(blank=True)
def __str__(self):
return self.name
class Challenge(models.Model):
id = models.AutoField(primary_key=True)
creator = models.ForeignKey(User)
name = models.CharField(max_length=256)
description = models.TextField(blank=True)
tags = models.ManyToManyField(ChallengeTag, blank=True)
def __str__(self):
return self.name
class UserChallenge(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(User)
challenge = models.ForeignKey(Challenge)

View File

@ -1,106 +0,0 @@
from django.http import HttpResponse
from django.shortcuts import render
from django.views.decorators.csrf import csrf_protect
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from .models import *
def index(request):
if request.method == 'GET':
data = {
'challenges': Challenge.objects.all()[:4]
}
return render(request, 'index.html', data)
@csrf_protect
def register(request):
if request.method == 'GET':
return render(request, 'register.html')
elif request.method == 'POST':
username = request.POST['user']
password = request.POST['pw']
password_confirmation = request.POST['password_confirmation']
if len(password) < 8:
return HttpResponse("password too short")
if password != password_confirmation:
return HttpResponse("passwords do not match")
if not User.objects.filter(username=username).exists():
user = User.objects.create_user(username, password=password)
user.save()
else:
return HttpResponse("user exist")
return HttpResponse("User {} created".format(username))
@csrf_protect
def login_view(request):
if request.method == 'GET':
auth_user = 'no user'
if request.user.is_authenticated:
auth_user = request.user.username
return render(request, 'login.html', {'auth_user': auth_user})
elif request.method == 'POST':
username = request.POST['user']
password = request.POST['pw']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return HttpResponse('request suq')
else:
return HttpResponse('invalid username or password')
def logout_view(request):
logout(request)
return HttpResponse('logged out')
def challenge(request, id):
if request.method == 'GET':
data = {
'challenge': Challenge.objects.get(id=id)
}
return render(request, 'challenge.html', data)
elif request.method == 'POST':
if not request.user.is_authenticated:
return HttpResponse('not logged in')
challenge_name = request.POST['challenge_name']
challenge_description = request.POST['challenge_discription']
tags = []
new_challenge = Challenge(creator=request.user, name=challenge_name, description=challenge_description, tags=tags)
new_challenge.save()
def challenges(request):
if request.method == 'GET':
data = {
'challenges': Challenge.objects.all()
}
return render(request, 'challenges.html', data)
def hall_of_fame(request):
if request.method == 'GET':
data = {
'users': sorted(User.objects.all(), key=lambda x: len(UserChallenge.objects.filter(user=x)), reverse=True)
}
return render(request, 'hall_of_fame.html', data)
def profile(request, username=''):
if request.method == 'GET':
user = User.objects.get(username=username)
user_challenges = UserChallenge.objects.filter(user=user)
data = {
'user': user,
'challenges': user_challenges
}
return render(request, 'profile.html', data)

36
kspace/admin.py Normal file
View File

@ -0,0 +1,36 @@
from django.contrib import admin
from kspace.models import *
class ChallengeAdmin(admin.ModelAdmin):
list_display = ('name', 'description', 'creator',)
def save_model(self, request, obj, form, change):
if getattr(obj, 'creator', None) is None:
obj.creator = request.user
obj.save()
class InventoryItemAdmin(admin.ModelAdmin):
list_display = ('item_name', 'serial_nr', 'hidden', 'usable', 'owner', 'creator',)
def save_model(self, request, obj, form, change):
if getattr(obj, 'creator', None) is None:
obj.creator = request.user
obj.save()
class InventoryItemLocationAdmin(admin.ModelAdmin):
list_display = ('location', 'parent',)
class Media:
js = ('/static/admin/js/hide_attribute.js',)
admin.site.register(Challenge, ChallengeAdmin)
admin.site.register(ChallengeTag)
admin.site.register(UserChallenge)
admin.site.register(Profile)
admin.site.register(InventoryItemOwner)
admin.site.register(InventoryItemLocation, InventoryItemLocationAdmin)
admin.site.register(InventoryItem, InventoryItemAdmin)

111
kspace/models.py Normal file
View File

@ -0,0 +1,111 @@
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
from location_field.models.plain import PlainLocationField
import os
def get_profile_image_path(instance, filename):
return os.path.join('icons', str(instance.id), filename)
def get_inventory_item_path(instance, filename):
return os.path.join('inventory', str(instance.id))
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
icon = models.ImageField(upload_to=get_profile_image_path, default='default_icon.png')
phone_number = models.CharField(max_length=16, blank=True, null=True)
contact_info = models.TextField(blank=True, null=True)
def __str__(self):
return self.user.username
class ChallengeTag(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
description = models.TextField(blank=True)
def __str__(self):
return self.name
class InventoryItemOwner(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, blank=True, null=True, editable=False)
name = models.CharField(max_length=64)
def __str__(self):
if self.user is not None:
return self.user.username
else:
return self.name
class InventoryItemLocation(models.Model):
id = models.AutoField(primary_key=True)
parent = models.ForeignKey("self", blank=True, null=True, on_delete=models.SET_NULL)
address = models.BooleanField(default=True)
location = models.CharField(max_length=256)
gps_location = PlainLocationField(based_fields=['location'], blank=True, null=True)
def __str__(self):
return self.location
class InventoryItem(models.Model):
id = models.AutoField(primary_key=True)
item_name = models.CharField(max_length=256)
serial_nr = models.CharField(max_length=32, default='', blank=True, null=True)
hidden = models.BooleanField(default=True)
owner = models.ForeignKey(InventoryItemOwner, related_name="%(class)s_item", blank=True, null=True,
on_delete=models.SET_NULL)
value = models.IntegerField(blank=True, null=True)
location = models.ForeignKey(InventoryItemLocation, blank=True, null=True, on_delete=models.SET_NULL)
usable = models.BooleanField(default=True)
fixable = models.BooleanField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
destroyed = models.DateTimeField(blank=True, null=True)
creator = models.ForeignKey(User, related_name="%(class)s_created", blank=True, null=True, editable=False,
on_delete=models.SET_NULL)
description = models.TextField(blank=True, null=True)
photo = models.ImageField(upload_to=get_inventory_item_path, blank=True, null=True)
def __str__(self):
return self.item_name
class Challenge(models.Model):
id = models.AutoField(primary_key=True)
creator = models.ForeignKey(User, blank=True, null=True, editable=False, on_delete=models.SET_NULL)
name = models.CharField(max_length=64)
blurb = models.CharField(max_length=140, blank=True, null=True)
description = models.TextField(blank=True, null=True)
required_items = models.ManyToManyField(InventoryItem, blank=True)
tags = models.ManyToManyField(ChallengeTag, blank=True)
recurring = models.BooleanField(default=False)
def __str__(self):
return self.name
class UserChallenge(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)
challenge = models.ForeignKey(Challenge, blank=True, null=True, on_delete=models.SET_NULL)
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
InventoryItemOwner.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
instance.inventoryitemowner.save()

View File

@ -1,5 +1,5 @@
""" """
Django settings for challenges project. Django settings for kspace project.
Generated by 'django-admin startproject' using Django 1.11.6. Generated by 'django-admin startproject' using Django 1.11.6.
For more information on this file, see For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/ https://docs.djangoproject.com/en/1.11/topics/settings/
@ -22,7 +22,7 @@ SECRET_KEY = 'gze3mreum6caz26_k2zq8(zn+)v3pdfaup+-e20eu@vca5st=b'
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True DEBUG = True
ALLOWED_HOSTS = ['k-space.ee', '127.0.0.1'] ALLOWED_HOSTS = ['k-space.ee', 'kspace', '127.0.0.1', '10.179.42.230']
# Application definition # Application definition
@ -34,7 +34,9 @@ INSTALLED_APPS = [
'django.contrib.sessions', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'challenges' 'location_field.apps.DefaultConfig',
'markdownify',
'kspace'
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@ -47,7 +49,7 @@ MIDDLEWARE = [
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
] ]
ROOT_URLCONF = 'challenges.urls' ROOT_URLCONF = 'kspace.urls'
TEMPLATES = [ TEMPLATES = [
{ {
@ -66,7 +68,7 @@ TEMPLATES = [
}, },
] ]
WSGI_APPLICATION = 'challenges.wsgi.application' WSGI_APPLICATION = 'kspace.wsgi.application'
# Database # Database
@ -74,11 +76,31 @@ WSGI_APPLICATION = 'challenges.wsgi.application'
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.mysql',
'OPTIONS': {
'read_default_file': '/var/www/kspace/db.conf',
}
},
'debug': {
'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
} }
} }
MARKDOWNIFY_WHITELIST_TAGS = [
'a',
'abbr',
'acronym',
'b',
'blockquote',
'em',
'i',
'li',
'ol',
'p',
'strong',
'ul'
]
# Password validation # Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators

View File

@ -13,23 +13,21 @@ Including another URLconf
1. Import the include() function: from django.conf.urls import url, include 1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
""" """
from django.conf.urls import url
from django.contrib import admin
from django.conf import settings from django.conf import settings
from django.conf.urls import url
from django.conf.urls.static import static from django.conf.urls.static import static
from django.contrib import admin
from django.contrib.staticfiles.storage import staticfiles_storage from django.contrib.staticfiles.storage import staticfiles_storage
from django.views.generic.base import RedirectView from django.views.generic.base import RedirectView
from challenges import views from kspace import views
urlpatterns = [ urlpatterns = [
url(r'^$', views.index), url(r'^$', views.index),
url(r'^admin/', admin.site.urls), url(r'^admin/', admin.site.urls),
#url(r'^login/', views.login_view),
#url(r'^logout/', views.logout_view),
#url(r'^register/', views.register),
url(r'^challenge/(?P<id>[0-9]+)', views.challenge), url(r'^challenge/(?P<id>[0-9]+)', views.challenge),
url(r'^challenges/', views.challenges), url(r'^challenges/', views.challenges),
url(r'^halloffame/', views.hall_of_fame), url(r'^halloffame/', views.hall_of_fame),
url(r'^inventory/', views.inventory),
url(r'^profile/(?P<username>[\w.-]+)', views.profile), url(r'^profile/(?P<username>[\w.-]+)', views.profile),
url(r'^favicon.ico$', RedirectView.as_view(url=staticfiles_storage.url('favicon.ico'), permanent=False), name='favicon') url(r'^favicon.ico$', RedirectView.as_view(url=staticfiles_storage.url('favicon.ico'), permanent=False), name='favicon')
] + static(settings.STATIC_URL, document_root=settings.STATICFILES_DIRS) + \ ] + static(settings.STATIC_URL, document_root=settings.STATICFILES_DIRS) + \

63
kspace/views.py Normal file
View File

@ -0,0 +1,63 @@
from django.http import HttpResponse
from django.shortcuts import render
from kspace.models import *
def index(request):
if request.method == 'GET':
data = {
'challenges': Challenge.objects.all()[:4]
}
return render(request, 'index.html', data)
def challenge(request, id):
if request.method == 'GET':
data = {
'challenge': Challenge.objects.get(id=id)
}
return render(request, 'challenge.html', data)
elif request.method == 'POST':
if not request.user.is_authenticated:
return HttpResponse('not logged in')
challenge_name = request.POST['challenge_name']
challenge_description = request.POST['challenge_discription']
tags = []
new_challenge = Challenge(creator=request.user, name=challenge_name, description=challenge_description,
tags=tags)
new_challenge.save()
def challenges(request):
if request.method == 'GET':
data = {
'challenges': Challenge.objects.all()
}
return render(request, 'challenges.html', data)
def inventory(request):
if request.method == 'GET':
data = {
'inventory': InventoryItem.objects.all()
}
return render(request, 'inventory.html', data)
def hall_of_fame(request):
if request.method == 'GET':
data = {
'users': sorted(User.objects.all(), key=lambda x: len(UserChallenge.objects.filter(user=x)), reverse=True)
}
return render(request, 'hall_of_fame.html', data)
def profile(request, username=''):
if request.method == 'GET':
user = User.objects.get(username=username)
user_challenges = UserChallenge.objects.filter(user=user)
data = {
'user': user,
'challenges': user_challenges
}
return render(request, 'profile.html', data)

View File

@ -1,5 +1,5 @@
""" """
WSGI config for challenges project. WSGI config for kspace project.
It exposes the WSGI callable as a module-level variable named ``application``. It exposes the WSGI callable as a module-level variable named ``application``.
@ -11,6 +11,6 @@ import os
from django.core.wsgi import get_wsgi_application from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "challenges.settings") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kspace.settings")
application = get_wsgi_application() application = get_wsgi_application()

View File

@ -3,7 +3,7 @@ import os
import sys import sys
if __name__ == "__main__": if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "challenges.settings") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kspace.settings")
try: try:
from django.core.management import execute_from_command_line from django.core.management import execute_from_command_line
except ImportError: except ImportError:

0
media/default_icon.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

BIN
media/missing_photo.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

3
requirements.txt Normal file
View File

@ -0,0 +1,3 @@
django
django-location-field
django-markdownify

View File

@ -0,0 +1,21 @@
var hide_page = false;
django.jQuery(document).ready(function(){
if (django.jQuery('#id_address').is(':checked')) {
django.jQuery(".field-gps_location").show();
hide_page=true;
}
else {
django.jQuery(".field-gps_location").hide();
hide_page=false;
}
django.jQuery("#id_address").click(function(){
hide_page = !hide_page;
if(hide_page) {
django.jQuery(".field-gps_location").show();
}
else {
django.jQuery(".field-gps_location").hide();
}
})
});

View File

@ -14,10 +14,6 @@ footer, .map {
background-color: #34495e !important; background-color: #34495e !important;
} }
.card {
width: 300px;
margin: 0 auto;
}
.progress { .progress {
height:10px; height:10px;
@ -27,16 +23,15 @@ footer, .map {
margin-top: 30px; margin-top: 30px;
} }
a:link, a:visited { .lightlink:link, .lightlink:visited {
color: white; color: white;
} }
a:hover { .lightlink:hover {
color: #34495e; color: #34495e;
} }
.lightlink:active {
a:active {
color: black; color: black;
} }
@ -49,10 +44,34 @@ ul {
width:300px; width:300px;
} }
.card-image.img {
display: block;
max-height: 300px;
max-width: 300px;
height: auto;
width: auto;
}
.card .inventory .card-content {
max-height: 100px;
}
.card.small { .card.small {
height: auto; height: auto;
} }
a:link, a:visited {
color: #3498db;
}
a:hover {
color: #34495e;
}
a:active, a.highlight:hover {
color: black;
}
.darklink:link, .darklink:visited { .darklink:link, .darklink:visited {
color: black; color: black;
} }
@ -61,10 +80,6 @@ ul {
color: #34495e; color: #34495e;
} }
.darklink:active { .darklink:active, .darklink.highlight:hover {
color: #3498db; color: #3498db;
} }
a.highlight:hover{
color: #3498db;
}

View File

@ -8,8 +8,6 @@ h1, h2 {
.headerblock { .headerblock {
height: 25em; height: 25em;
/*background-image: url("http://robot.itcollege.ee/assets/img/sumoesp-soldered.jpg");*/
/*background-size: cover;*/
position: relative; position: relative;
overflow: hidden; overflow: hidden;
z-index: 0; z-index: 0;
@ -75,9 +73,6 @@ ul {
font-size: 14pt; font-size: 14pt;
} }
a:link, a:visited {
color: white;
}
a:hover { a:hover {
color: #34495e; color: #34495e;
@ -89,3 +84,24 @@ a:active {
a.highlight:hover{ a.highlight:hover{
color: #3498db; color: #3498db;
} }
.card-title {
white-space: nowrap;
}
.gallery {
padding: 0 auto;
white-space: nowrap;
width: 100%;
height: 200px;
overflow: hidden;
overflow-x: scroll;
}
.gallery img {
display: inline-block;
margin: 0;
padding: 0;
max-width: 100%;
max-height: 100%;
}

View File

@ -4,7 +4,7 @@
{% extends 'base_footer.html' %} {% extends 'base_footer.html' %}
{% block base_footer %} {% block base_footer %}
<div class="header section center-align"> <div class="header section center-align">
<h1 class="section darken-2 z-depth-1 white-text"><a href="/">k-space.ee</a></h1> <h1 class="section darken-2 z-depth-1 white-text"><a href="/" class="lightlink">k-space.ee</a></h1>
</div> </div>
{% block content %} {% block content %}

View File

@ -19,25 +19,26 @@
<div class="col l6 s12"> <div class="col l6 s12">
<h5 class="white-text">Contact</h5> <h5 class="white-text">Contact</h5>
<p class="grey-text text-lighten-4"> <p class="grey-text text-lighten-4">
<i class="material-icons">phone</i> Phone: +372 5332 9412 <i class="material-icons">person</i> Lauri Võsandi<br/>
<br> <i class="material-icons">phone</i> +372 5332 9412<br/>
<i class="material-icons">email</i> Email: lauri.vosandi@gmail.com <i class="material-icons">email</i> lauri.vosandi@gmail.com
</p> </p>
<h5 class="white-text">Sponsors</h5> <h5 class="white-text">Partners</h5>
<p class="grey-text text-lighten-4"> <p class="grey-text text-lighten-4">
We have more than 10 companies supporting us financially and by equipment <ul>
</br> <li>Thorgate</li>
<a class="highlight" href="#">I want to become a sponsor</a> <li>Stork Drives</li>
<li>Tallinn University of Technology</li>
<li>3D Partner</li>
</ul>
Contact us if you want to become a sponsor
</p> </p>
</div> </div>
<div class="col l4 offset-l2 s12"> <div class="col l4 offset-l2 s12">
<h5 class="white-text">Links</h5> <h5 class="white-text">Links</h5>
<ul> <p>We're located at Akadeemia tee 21/1, fifth floor. You can take elevator to 4th floor and then take stairs to the 5th</p>
<li><a class="highlight" href="#!">Mission</a></li>
<li><a class="highlight" href="#!">People</a></li>
</ul>
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d1015.5421689053422!2d24.659768056865254!3d59.39830538168295!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x469295abf80677bd%3A0x89a6e8a5671f608b!2sAkadeemia+tee+21%2F1%2C+12618+Tallinn!5e0!3m2!1set!2see!4v1507405326247" <iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d1015.5421689053422!2d24.659768056865254!3d59.39830538168295!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x469295abf80677bd%3A0x89a6e8a5671f608b!2sAkadeemia+tee+21%2F1%2C+12618+Tallinn!5e0!3m2!1set!2see!4v1507405326247"
width="350" height="200" frameborder="0" style="border:0" allowfullscreen></iframe> width="350" height="200" frameborder="0" style="border:0" allowfullscreen></iframe>
</div> </div>
@ -45,8 +46,13 @@
</div> </div>
<div class="footer-copyright"> <div class="footer-copyright">
<div class="container"> <div class="container">
© 2017 k-space © 2017 K-SPACE MTÜ<br/>
<!-- <a class="grey-text text-lighten-4 right" href="#!">More Links</a> --> Registration number 80397632<br/>
IBAN EE467700771002926893
<br/>
<br/>
<br/>
<br/>
</div> </div>
</div> </div>
</footer> </footer>

View File

@ -1,54 +1,68 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load markdownify %}
{% block content %} {% block content %}
<div class="row container"> <div class="row container">
<div class="row"> <div class="row">
<div class="col m8"> <div class="col m8">
<h3 class="">{{ challenge.name }}</h3> <h3 class="">{{ challenge.name }}</h3>
<div> {% if challenge.description %}
{% for tag in challenge.tags.all %} <p style="">{{ challenge.description | markdownify }}</p>
<div class="chip">{{ tag.name }}</div> {% else %}
{% endfor %} <p style="">{{ challenge.blurb | markdownify }}</p>
</div> {% endif %}
<p style="">{{ challenge.description }}
</p>
<div class="section"> <div class="section">
<p>I am usually at k-space on weekends. Come and take a look.</p> {% if challenge.creator.profile.contact_info %}
<div class="valign-wrapper"><i class="material-icons">email</i>&nbsp; eric.cartman@email.com</div> <p>{{ challenge.creator.profile.contact_info }}</p>
<br> {% endif %}
<div class="valign-wrapper"><i class="material-icons">phone</i>&nbsp;55 55 5555</div> {% if challenge.creator.email %}
<div class="valign-wrapper"><i class="material-icons">email</i>&nbsp;{{ challenge.creator.email }}</div>
<br>
{% endif %}
{% if challenge.creator.profile.phone_number %}
<div class="valign-wrapper"><i
class="material-icons">phone</i>&nbsp;{{ challenge.creator.profile.phone_number }}</div>
{% endif %}
</div> </div>
</div> </div>
<div class="col m4"> <div class="col m4">
<ul class="collection"> <ul class="collection">
<li class="collection-item avatar"> <li class="collection-item avatar">
<img src="https://vignette.wikia.nocookie.net/southpark/images/0/0d/1a.jpg/revision/latest/scale-to-width-down/310?cb=20100826182516" <img src="/media/{{ challenge.creator.profile.icon }}"
alt="" class="circle"> alt="" class="circle">
<span class="title">Author</span> <span class="title">Author</span>
<p><b>{{ challenge.creator.username }}</b></p> <p><b>{{ challenge.creator.get_full_name }}</b></p>
</li>
<li class="collection-item">
<span class="title">Programming</span>
</li>
<li class="collection-item">
<span class="title">Soldering</span>
</li> </li>
</ul> </ul>
<ul class="collection with-header"> {% if challenge.tags.all %}
<li class="collection-header"> <p>Relevant keywords:</p>
<span class="title"><b>What we need</b></span> <ul class="browser-default">
</li> {% for tag in challenge.tags.all %}
<li class="collection-item"> <li class="collection-item">
<span class="">CNC bench experience</span> <span class="">{{ tag.name }}</span>
</li> </li>
<li class="collection-item"> {% endfor %}
<span class="title">Screwdriver</span>
</li>
</ul> </ul>
{% endif %}
{% if challenge.required_items.all %}
<p>Relevant inventory:</p>
<ul class="browser-default">
{% for item in challenge.required_items.all %}
{% if not item.hidden %}
<li class="collection-item">
<span class="">{{ item.item_name }}</span>
</li>
{% endif %}
{% endfor %}
</ul>
{% endif %}
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,4 +1,7 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load markdownify %}
{% block content %} {% block content %}
<div class="row container"> <div class="row container">
<div class="section slogan"> <div class="section slogan">
@ -10,28 +13,29 @@
<div class="row"> <div class="row">
{% for challenge in challenges %} {% for challenge in challenges %}
<div class="col s12 m4"> <div class="col s12 m4">
<div class="card" style="height:350px;"> <div class="card">
<div class="card-content">
<div class="row" style="height:210px;">
<div class="col s12 m12"> <div class="card-content" style="overflow: hidden; height:200px;">
<div class="card-title"><b>{{ challenge.name }}</b></div> <div class="card-title"><b>{{ challenge.name }}</b></div>
<p style="text-align: justify; max-height: 120px; overflow: auto;">{{ challenge.description }}</p> <p style="text-align: justify;">
<div style="padding-top: 15px;"> {% if challenge.blurb %}
{% for tag in challenge.tags.all %} {{ challenge.blurb | markdownify }}
<div class="chip">{{ tag.name }}</div> {% else %}
{% endfor %} {{ challenge.description|slice:":500" | markdownify }}
</div> {% endif %}
</div> </p>
</div> <div style="padding-top: 15px;">
</br> {% for tag in challenge.tags.all %}
<div class="row"> <div class="chip">{{ tag.name }}</div>
<div class="col s12 m12"> {% endfor %}
<div class="center-align">
<a href="/challenge/{{ challenge.id }}" class="btn-large">I can do it</a>
</div>
</div>
</div> </div>
</div> </div>
<div class="card-action">
<a href="/challenge/{{ challenge.id }}" class="btn-large lightlink">I can do it</a>
</div>
</div> </div>
</div> </div>
{% endfor %} {% endfor %}

View File

@ -8,6 +8,7 @@
<div class="row container section"> <div class="row container section">
{% for user in users %} {% for user in users %}
{% if user.first_name or user.last_name %}
<div class="col s12 m4"> <div class="col s12 m4">
<div class="section center-align"> <div class="section center-align">
<div class="card"> <div class="card">
@ -15,8 +16,8 @@
<div class="card-image"> <div class="card-image">
<a href="/profile/{{ user.username }}"><img src='/media/{{ user.profile.icon }}'></a> <a href="/profile/{{ user.username }}"><img src='/media/{{ user.profile.icon }}'></a>
</div> </div>
<h5 class="card-title" style="padding-top: 10px;color:black;"><a class='darklink' <h5 class="card-title" style="padding-top: 10px;color:black;">
href="/profile/{{ user.username }}"><b>{{ user.username }}</b></a> <a class='darklink' href="/profile/{{ user.username }}"><b>{{ user.first_name }} {{ user.last_name }}</b></a>
</h5> </h5>
<div class="row"> <div class="row">
<div class="col s12 m1"> <div class="col s12 m1">
@ -43,6 +44,7 @@
</div> </div>
</div> </div>
</div> </div>
{% endif %}
{% endfor %} {% endfor %}
</div> </div>
{% endblock %} {% endblock %}

View File

@ -1,5 +1,5 @@
<head> <head>
<link rel="stylesheet" href="/static/css/index.css"> <link rel="stylesheet" href="/static/css/index.css?ts=100">
</head> </head>
{% extends 'base_footer.html' %} {% extends 'base_footer.html' %}
@ -8,7 +8,7 @@
<div class="headerblock section"> <div class="headerblock section">
<div class="fadeimage" <div class="fadeimage"
style="opacity:1;background-image:url('http://robot.itcollege.ee/assets/img/sumoesp-soldered.jpg')"></div> style="opacity:1;background-image:url('//media.k-space.ee/sumoesp-soldered.jpg')"></div>
<!-- <div class="fadeimage" style="background-image:url('https://owncloud.koodur.com/index.php/apps/gallery/preview.public/1092117?width=2600&height=2600&c=d21f5a223e7ae8c692c537e6a35ae37f&requesttoken=TGJTDncMBCtJEG40Djt9HSUBIykoWn4bNwQpP09YAx4%3D%3A85kCFd3z8QYaaAKggYmQi%2F0mtMcmz7iSGQBOmq84Z50%3D&token=j0HUdRNEaZ37wGE')"></div> <!-- <div class="fadeimage" style="background-image:url('https://owncloud.koodur.com/index.php/apps/gallery/preview.public/1092117?width=2600&height=2600&c=d21f5a223e7ae8c692c537e6a35ae37f&requesttoken=TGJTDncMBCtJEG40Djt9HSUBIykoWn4bNwQpP09YAx4%3D%3A85kCFd3z8QYaaAKggYmQi%2F0mtMcmz7iSGQBOmq84Z50%3D&token=j0HUdRNEaZ37wGE')"></div>
<div class="fadeimage" style="background-image:url('https://owncloud.koodur.com/index.php/apps/gallery/preview.public/1055905?width=2600&height=2600&c=a635e088958188e4490b17a91602366a&requesttoken=TGJTDncMBCtJEG40Djt9HSUBIykoWn4bNwQpP09YAx4%3D%3A85kCFd3z8QYaaAKggYmQi%2F0mtMcmz7iSGQBOmq84Z50%3D&token=j0HUdRNEaZ37wGE')"></div> --> <div class="fadeimage" style="background-image:url('https://owncloud.koodur.com/index.php/apps/gallery/preview.public/1055905?width=2600&height=2600&c=a635e088958188e4490b17a91602366a&requesttoken=TGJTDncMBCtJEG40Djt9HSUBIykoWn4bNwQpP09YAx4%3D%3A85kCFd3z8QYaaAKggYmQi%2F0mtMcmz7iSGQBOmq84Z50%3D&token=j0HUdRNEaZ37wGE')"></div> -->
@ -93,7 +93,7 @@
<a class="btn-large blue" href="/challenges">to ideas</a> <a class="btn-large blue" href="/challenges">to ideas</a>
</div> </div>
<div class="col s12 m4"> <div class="col s12 m4">
<a href="#" class="btn-large amber ">to equipment</a> <a href="/inventory" class="btn-large amber ">to equipment</a>
</div> </div>
<div class="col s12 m4"> <div class="col s12 m4">
<a href="/halloffame" class="btn-large green ">to success</a> <a href="/halloffame" class="btn-large green ">to success</a>
@ -126,134 +126,21 @@
<div class="col s1">&nbsp;</div> <div class="col s1">&nbsp;</div>
<div class="col s1">Office 20m<sup>2</sup></div> <div class="col s1">Office 20m<sup>2</sup></div>
<div class="col s1">&nbsp;</div> <div class="col s1">&nbsp;</div>
</div> </div>
</div> </div>
<div class="container"> <div class="container">
{% include "map.svg" %}
<!-- SVG START -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 802.7 239.1" style="enable-background:new 0 0 802.7 239.1;" xml:space="preserve">
<style type="text/css">
.st0 {
fill: #26719B;
stroke: #34495E;
stroke-width: 5;
stroke-miterlimit: 10;
}
.st1 {
fill: #3498DB;
stroke: #34495E;
stroke-width: 5;
stroke-miterlimit: 10;
}
.st2 {
fill: #ECF0F1;
stroke: #ECF0F1;
stroke-miterlimit: 10;
}
.st3 {
fill: #ECF0F1;
stroke: #ECF0F1;
stroke-width: 0.5;
stroke-miterlimit: 10;
}
.st4 {
fill: none;
stroke: #ECF0F1;
stroke-miterlimit: 10;
}
</style>
<g id="bg">
</g>
<g id="Layer_1">
<g id="XMLID_20_">
<rect id="XMLID_14_" x="67.2" y="70.6" class="st0" width="265.8" height="29.8"/>
<rect id="XMLID_16_" x="399.4" y="70.6" class="st0" width="265.8" height="29.8"/>
</g>
<g id="XMLID_17_">
<rect id="XMLID_1_" x="0" y="100.9" class="st1" width="333" height="40.2"/>
<rect id="XMLID_4_" x="67.2" y="141.2" class="st1" width="66.4" height="66.4"/>
<rect id="XMLID_5_" x="0" y="176.4" class="st1" width="67.2" height="31.2"/>
<rect id="XMLID_6_" x="133.6" y="141.2" class="st1" width="66.4" height="66.4"/>
<rect id="XMLID_7_" x="333" y="141.2" class="st1" width="66.4" height="66.4"/>
<polygon id="XMLID_3_" class="st1" points="33.6,100.4 0,100.4 0,46.3 14.3,31.5 33.6,31.5 "/>
<rect id="XMLID_2_" x="398.9" y="100.4" class="st1" width="265.8" height="40.2"/>
<rect id="XMLID_13_" x="531.8" y="140.6" class="st1" width="66.4" height="66.4"/>
<rect id="XMLID_11_" x="598.3" y="140.6" class="st1" width="66.4" height="66.4"/>
<polygon id="XMLID_8_" class="st1" points="698.3,100.4 664.7,100.4 664.7,46.3 679,31.5 698.3,31.5 "/>
<rect id="XMLID_10_" x="333" y="100.9" class="st1" width="66.4" height="40.2"/>
<polygon id="XMLID_12_" class="st1" points="365.3,100.4 398.9,100.4 398.9,46.3 384.6,31.5 365.3,31.5 "/>
<polygon id="XMLID_9_" class="st1" points="769.2,207.1 732.2,207.1 732.2,140.6 664.7,140.6 664.7,100.4 769.2,100.4 "/>
</g>
</g>
<g id="jooned">
<g id="XMLID_212_">
<line id="XMLID_214_" class="st2" x1="16.3" y1="65.9" x2="16.3" y2="0"/>
<ellipse id="XMLID_213_" class="st3" cx="16.3" cy="65.9" rx="4" ry="3.9"/>
</g>
<g id="XMLID_209_">
<line id="XMLID_211_" class="st2" x1="166" y1="121.1" x2="166" y2="-0.2"/>
<ellipse id="XMLID_210_" class="st3" cx="166" cy="121.1" rx="4" ry="3.9"/>
</g>
<g id="XMLID_206_">
<line id="XMLID_208_" class="st2" x1="565" y1="120.6" x2="565" y2="-0.7"/>
<ellipse id="XMLID_207_" class="st3" cx="565" cy="120.6" rx="4" ry="3.9"/>
</g>
<g id="XMLID_203_">
<polyline id="XMLID_205_" class="st4" points="382.1,66 348.6,66 348.6,0 "/>
<ellipse id="XMLID_204_" class="st3" cx="382.1" cy="66" rx="3.9" ry="4"/>
</g>
<g id="XMLID_200_">
<line id="XMLID_202_" class="st2" x1="681.5" y1="65.7" x2="681.5" y2="-0.2"/>
<ellipse id="XMLID_201_" class="st3" cx="681.5" cy="65.7" rx="4" ry="3.9"/>
</g>
<g id="XMLID_197_">
<line id="XMLID_199_" class="st2" x1="33.1" y1="191.4" x2="33.1" y2="239.1"/>
<ellipse id="XMLID_198_" class="st3" cx="33.1" cy="191.4" rx="4" ry="3.9"/>
</g>
<g id="XMLID_194_">
<line id="XMLID_196_" class="st2" x1="99.9" y1="174.1" x2="99.9" y2="239.1"/>
<ellipse id="XMLID_195_" class="st3" cx="99.9" cy="173.8" rx="4" ry="3.9"/>
</g>
<g id="XMLID_191_">
<polyline id="XMLID_193_" class="st4" points="166.8,174.4 230.9,174.4 230.9,239.1 "/>
<ellipse id="XMLID_192_" class="st3" cx="166.8" cy="174.4" rx="3.9" ry="4"/>
</g>
<g id="XMLID_188_">
<line id="XMLID_190_" class="st2" x1="365.7" y1="173.8" x2="365.7" y2="239.2"/>
<ellipse id="XMLID_189_" class="st3" cx="365.7" cy="173.8" rx="4" ry="3.9"/>
</g>
<g id="XMLID_185_">
<line id="XMLID_187_" class="st2" x1="565" y1="173.8" x2="565" y2="239.1"/>
<ellipse id="XMLID_186_" class="st3" cx="565" cy="173.8" rx="4" ry="3.9"/>
</g>
<g id="XMLID_182_">
<line id="XMLID_184_" class="st2" x1="631.5" y1="173.8" x2="631.5" y2="239.1"/>
<ellipse id="XMLID_183_" class="st3" cx="631.5" cy="173.8" rx="4" ry="3.9"/>
</g>
</g>
</svg>
</div> </div>
<div class="container white-text" id="svgtext"> <div class="container white-text" id="svgtext">
<div class="row"> <div class="row">
<div class="col s1">Servers</div> <div class="col s1">Hangout area</div>
<div class="col s2">3D printers, lasercutter, soldering</div> <div class="col s2">Lounge, PC-s, IoT lab</div>
<div class="col s2">CNC machine, saw, lathe, mill</div> <div class="col s2">Meeting room</div>
<div class="col s2">Kitchen, toilet, sauna</div> <div class="col s2">Kitchen, toilet, sauna</div>
<div class="col s2">Soldering irons, reflow oven, robotics lab</div>
<div class="col s1">&nbsp;</div> <div class="col s3">CNC machine, saw, lathe, mill, 3D printers, lasercutter</div>
<div class="col s1">Meeting room</div>
<div class="col s1">Lounge</div>
<div class="col s1">&nbsp;</div>
<div class="col s1">&nbsp;</div>
</div> </div>
</div> </div>
</div> </div>
@ -285,7 +172,7 @@
<div class="card-content"> <div class="card-content">
<div class="card-title">{{ challenge.name }}</div> <div class="card-title">{{ challenge.name }}</div>
<p style="text-align: justify; max-height: 120px; overflow: auto;">{{ challenge.description }}</p> <p style="height: 6em; overflow: auto;">{{ challenge.description }}</p>
</br> </br>
<div> <div>
{% for tag in challenge.tags.all %} {% for tag in challenge.tags.all %}
@ -306,5 +193,280 @@
</div> </div>
</div> </div>
<div class="section map z-depth-1">
<div class="container white-text">
<div class="row" style="margin-top: 32px">
<div class="col s12 m6">
<h2 class="">Team</h2>
</div>
</div>
<div class="row">
<p>We have our roots in the Robotics Club of Estonian IT College as
several key memebers are graduates of the College and were active Robotics Club members in the past.
Most of us have numerous years of work experience in ICT sector and we've travelled the world to see how hackerspaces and makerspaces operate.
We know that we've got what it takes to operate k-space.
</p>
<div class="col s12 m3 black-text">
<div class="card">
<div class="card-image">
<img src="https://media.licdn.com/mpr/mpr/shrinknp_200_200/p/8/000/1ad/2da/203cd14.jpg">
</div>
<div class="card-content">
<div class="card-title">Lauri Võsandi</div>
<p style="height: 6em; overflow: auto;">Founder of the k-space.
<a href="http://www.lpi.org/our-certifications/lpic-3-300-overview">Certified Linux expert</a>. Python developer and systems integrator.</p>
</div>
</div>
</div>
<div class="col s12 m3 black-text">
<div class="card">
<div class="card-image">
<img src="https://media-exp2.licdn.com/mpr/mpr/shrinknp_200_200/AAEAAQAAAAAAAAetAAAAJDA1ZTNlMTA0LTJlZTEtNGM1NC05YzE3LTI4NDg0MzhmMjE5MQ.jpg"/>
</div>
<div class="card-content">
<div class="card-title">Allan Vein</div>
<p style="height: 6em; overflow: auto;">Mr Inappropriate<br/>&nbsp;</p>
</div>
</div>
</div>
<div class="col s12 m3 black-text">
<div class="card">
<div class="card-image">
<img src="//media.k-space.ee/members/erki.jpg"/>
</div>
<div class="card-content">
<div class="card-title">Erki Naumanis</div>
<p style="height: 6em; overflow: auto;">
<a href="http://www.mesinikeliit.ee/aasta-mesinik-2016/">Beekeeper of the year 2016</a>. Builder of smart Internet enabled beehives</p>
</div>
</div>
</div>
<div class="col s12 m3 black-text">
<div class="card">
<div class="card-image">
<img src="https://pbs.twimg.com/profile_images/2548581494/2011-06-22--02-timmu-and-laes_400x400.jpg"/>
</div>
<div class="card-content">
<div class="card-title">Priit Laes</div>
<p style="height: 6em; overflow: auto;">Embedded Linux systems expert and kernel developer</p>
</div>
</div>
</div>
<div class="col s12 m3 black-text">
<div class="card">
<div class="card-image">
<img src="//media.k-space.ee/members/silver.jpg"/>
</div>
<div class="card-content">
<div class="card-title">Silver Kuusik</div>
<p style="height: 6em; overflow: auto;">Electronics schematic design & software development. Founder of <a href="http://www.robokoding.com/">Robokoding</a></p>
</div>
</div>
</div>
<div class="col s12 m3 black-text">
<div class="card">
<div class="card-image">
<img src="//media.k-space.ee/minion.jpg"/>
</div>
<div class="card-content">
<div class="card-title">Marek Juhanson</div>
<p style="height: 6em; overflow: auto;">3D printing and product design</p>
</div>
</div>
</div>
<div class="col s12 m3 black-text">
<div class="card">
<div class="card-image">
<img src="//media.k-space.ee/minion.jpg"/>
</div>
<div class="card-content">
<div class="card-title">Jaan Jänesmäe</div>
<p style="height: 6em; overflow: auto;">Drone building and 3D printing</p>
</div>
</div>
</div>
</div>
<p>Interested in joining the core team? Give Lauri a call and schedule for a visit.</p>
</div>
</div>
<div class="container black-text">
<div class="row" style="margin-top: 32px">
<div class="col s12">
<h2 class="" id="services">Events</h2>
</div>
</div>
<div class="row">
<div class="col s12 m6">
<p>In addition to the regular and not so regular events on the right we're in talks about hosting following as well:</p>
<ul class="browser-default">
<li>Laphack</li>
<li>Python CodeClub</li>
<li>Cryptocurrency interest groups</li>
<li>Robotex prep arena</li>
</ul>
</div>
<div class="col s12 m6">
<iframe src="https://calendar.google.com/calendar/embed?showTitle=0&amp;showNav=0&amp;showDate=0&amp;showPrint=0&amp;showTabs=0&amp;showCalendars=0&amp;showTz=0&amp;mode=AGENDA&amp;height=400&amp;wkst=2&amp;hl=en&amp;bgcolor=%23FFFFFF&amp;src=m5irb4eke9npgk25nrb4qh41v4%40group.calendar.google.com&amp;color=%236B3304&amp;ctz=Europe%2FTallinn" style="border-width:0" width="100%" height="400" frameborder="0" scrolling="no"></iframe>
</div>
</div>
</div>
<div class="container black-text">
<div class="row" style="margin-top: 32px">
<div class="col s12">
<h2 class="" id="services">For individuals</h2>
</div>
</div>
<div class="row">
<p>For individuals we have several offers:</p>
<ul class="browser-default">
<li>Environment to learn about the latest trends in IT and tech down to the hardware and electronics level</li>
<li>Looking for a particular gadget to test out your idea? Raspberry Pi? Arduino? We got you covered!</li>
<li>Location for you interest group activities, see more info <a href="https://wiki.k-space.ee/index.php?title=Events" target="_blank">here</a></li>
<li>Use our equipment, we've got soldering stations, CNC machines, 3D printers and more</li>
<li>Office space for your personal projects or freelance work. Renting a whole office on your own might not make sense, why not join us?</li>
<li>As a bonus we also have a server room so you can get your machine up and online in no time</li>
</ul>
</div>
<div class="row">
<div class="col s12 m4">
<div class="card">
<div class="card-content">
<span class="card-title" style="font-family: 'Orbitron', cursive; font-size:200%;">Newbie</span>
<p>Beginner package the get you started at our hackerspace</p>
<ul class="browser-default">
<li>Access to rooms 24/7</li>
<li>Locker for personal belongings</li>
<li>Access to common equipment</li>
</ul>
<p style="text-align:right; font-size:200%;font-family: 'Orbitron', cursive;">29€/month</p>
</div>
</div>
</div>
<div class="col s12 m4">
<div class="card">
<div class="card-content">
<span class="card-title" style="font-family: 'Orbitron', cursive; font-size:200%;">Resident</span>
<p>In addition to the stuff on the left you get following for your freelance work or hobby projects:</p>
<ul class="browser-default">
<li>Personal desk</li>
<li>Personal shelf</li>
<li>Space in the server room</li>
</ul>
<p style="text-align:right; font-size:200%;font-family: 'Orbitron', cursive;">59€/month</p>
</div>
</div>
</div>
<div class="col s12 m4">
<div class="card">
<div class="card-content">
<span class="card-title" style="font-family: 'Orbitron', cursive; font-size:200%;">Office space</span>
<p>In addition to the stuff on the left you get:</p>
<ul class="browser-default">
<li>Dedicated section of the hackerspace for your activities</li>
</ul>
<p style="text-align:right; font-size:200%;font-family: 'Orbitron', cursive;">99€/month</p>
</div>
</div>
</div>
</div>
</div>
<div class="gallery" style="height:400px;">
<img src="//media.k-space.ee/nixiesp12.jpg"/
><img src="//media.k-space.ee/basketball-robots-front.jpg"/
><img src="//media.k-space.ee/nixiesp12-assembled.jpg"/
><img src="//media.k-space.ee/basketball.jpg"/
><img src="//media.k-space.ee/basketball-robot-base.jpg"/
><img src="//media.k-space.ee/sumod-arsenalis.jpg"/
><img src="//media.k-space.ee/sumoesp.jpg"/
><img src="//media.k-space.ee/mass-produced-pcbs.jpg"/
><img src="//media.k-space.ee/basketball-robots.jpg"/
>
</div>
<div class="container black-text">
<div class="row" style="margin-top: 32px">
<div class="col s12">
<h2 id="services">Services for students</h2>
</div>
</div>
<div class="row">
<p>For students we offer several interesting opportunities:</p>
<ul class="browser-default">
<li>Internship opportunities and supervision, suggest a topic yourself or ask Lauri</li>
<li>Desk and equipment for your thesis project, eg HackRF, Proxmark etc. Let us know what you need.</li>
<li>Practice for Locked Shields test run</li>
<li>Customized 3 ECTS course for your topic of interest</li>
<li>Funding and equipment to participate at Robotex</li>
</ul>
<p>
We participated with two football robots at Robotex 2016. Here's a sneak peek what the robot sees on-board:
</p>
</div>
</div>
<div style="position:relative;">
<video loop autoplay width="100%">
<source src="https://media.k-space.ee/zoidberg-football.mp4" type="video/mp4">
</video>
</div>
<div class="container black-text">
<div class="row" style="margin-top: 32px">
<div class="col s12">
<h2 class="" id="services">Corporate interests</h2>
</div>
</div>
<div class="row">
<p>We offer variety of interesting paid options for your company:</p>
<ul class="browser-default">
<li>Organize your corporate event at our place. We can help with the entertainment and you have opportunity to meet new potential employees.</li>
<li>Rent our gadgets and toys for a corporate event, eg sumorobots in your company's booth at a conference</li>
<li>Invite us to come and fill in with the entertainment portion of your corporate event</li>
<li>Location and equipment to carry out trainings ranging from Arduino-s, Raspberry Pi-s to radiocommunications and networking</li>
<li>Provide your employees location and equipment to engage in hobby activities eg. 3D printing and building quadricopters</li>
<li>Let us help with headhunting - provide us with a detailed description of what kind of people you're looking for and we'll help you to find them. Set up a roll-up stand at our hackerspace for more visibility. Send us your challenges, perhaps someone from here would like to tackle it.</li>
<li>Corporate visibility at international robotics competiton Robotex. Our hackerspace members have participated repeatedly at the Robotex in the past. In 2018 we're planning to participate in the basketball robots and ICD grand challenge categories.</li>
</ul>
<p>Contact Lauri via e-mail address below for more information</p>
</div>
</div>
<br> <br>
{% endblock %} {% endblock %}

34
templates/inventory.html Normal file
View File

@ -0,0 +1,34 @@
{% extends 'base.html' %}
{% block content %}
<div class="row container">
<div class="section slogan">
<h2 class="center-align" style="font-weight:bold">Inventory<br></h2>
</div>
</div>
<div class="row container challenges">
<div class="row">
{% for item in inventory %}
{% if not item.hidden %}
<div class="col s12 m3">
<div class="card">
<div class="card-content">
<div class="card-image">
{% if item.photo %}
<img src='/media/{{ item.photo }}'>
{% else %}
<img src='/media/missing_photo.png'>
{% endif %}
</div>
<div class="card-title"><b>{{ item.item_name }}</b></div>
<p>Serial: {{ item.serial_nr }}</p>
<p style="text-align: justify; max-height: 120px; overflow: auto;">{{ item.description }}</p>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
{% endblock %}

99
templates/logo.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 15 KiB

101
templates/map.svg Normal file
View File

@ -0,0 +1,101 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 802.7 239.1" style="enable-background:new 0 0 802.7 239.1;">
<style type="text/css">
.st0 {
fill: #26719B;
stroke: #34495E;
stroke-width: 5;
stroke-miterlimit: 10;
}
.st1 {
fill: #3498DB;
stroke: #34495E;
stroke-width: 5;
stroke-miterlimit: 10;
}
.st1:hover {
fill: #77b9e7;
transition: fill 0.3s;
}
.st3 {
fill: #ECF0F1;
stroke: #ECF0F1;
stroke-width: 0.5;
stroke-miterlimit: 10;
}
.st4 {
fill: none;
stroke: #ECF0F1;
stroke-miterlimit: 10;
}
</style>
<g>
<g>
<rect x="67.2" y="70.6" class="st0" width="265.8" height="29.8"/>
<rect x="399.4" y="70.6" class="st0" width="265.8" height="29.8"/>
</g>
<g>
<rect x="0" y="100.9" class="st1" width="333" height="40.2"/>
<rect x="67.2" y="141.2" class="st1" width="66.4" height="66.4"/>
<rect x="0" y="176.4" class="st1" width="67.2" height="31.2"/>
<rect x="133.6" y="141.2" class="st1" width="66.4" height="66.4"/>
<rect x="333" y="141.2" class="st1" width="66.4" height="66.4"/>
<polygon class="st1" points="33.6,100.4 0,100.4 0,46.3 14.3,31.5 33.6,31.5 "/>
<rect x="398.9" y="100.4" class="st1" width="265.8" height="40.2"/>
<rect x="531.8" y="140.6" class="st1" width="66.4" height="66.4"/>
<rect x="598.3" y="140.6" class="st1" width="66.4" height="66.4"/>
<polygon class="st1" points="698.3,100.4 664.7,100.4 664.7,46.3 679,31.5 698.3,31.5 "/>
<rect x="333" y="100.9" class="st1" width="66.4" height="40.2"/>
<polygon class="st1" points="365.3,100.4 398.9,100.4 398.9,46.3 384.6,31.5 365.3,31.5 "/>
<polygon class="st1" points="769.2,207.1 732.2,207.1 732.2,140.6 664.7,140.6 664.7,100.4 769.2,100.4 "/>
</g>
<g>
<line class="st4" x1="16.3" y1="65.9" x2="16.3" y2="0"/>
<ellipse class="st3" cx="16.3" cy="65.9" rx="4" ry="3.9"/>
</g>
<g>
<line class="st4" x1="166" y1="121.1" x2="166" y2="-0.2"/>
<ellipse class="st3" cx="166" cy="121.1" rx="4" ry="3.9"/>
</g>
<g>
<line class="st4" x1="565" y1="120.6" x2="565" y2="-0.7"/>
<ellipse class="st3" cx="565" cy="120.6" rx="4" ry="3.9"/>
</g>
<g>
<polyline class="st4" points="382.1,66 348.6,66 348.6,0 "/>
<ellipse class="st3" cx="382.1" cy="66" rx="3.9" ry="4"/>
</g>
<g>
<line class="st4" x1="681.5" y1="65.7" x2="681.5" y2="-0.2"/>
<ellipse class="st3" cx="681.5" cy="65.7" rx="4" ry="3.9"/>
</g>
<g>
<line class="st4" x1="33.1" y1="191.4" x2="33.1" y2="239.1"/>
<ellipse class="st3" cx="33.1" cy="191.4" rx="4" ry="3.9"/>
</g>
<g>
<line class="st4" x1="99.9" y1="174.1" x2="99.9" y2="239.1"/>
<ellipse class="st3" cx="99.9" cy="173.8" rx="4" ry="3.9"/>
</g>
<g>
<polyline class="st4" points="166.8,174.4 230.9,174.4 230.9,239.1 "/>
<ellipse class="st3" cx="166.8" cy="174.4" rx="3.9" ry="4"/>
</g>
<g>
<line class="st4" x1="365.7" y1="173.8" x2="365.7" y2="239.2"/>
<ellipse class="st3" cx="365.7" cy="173.8" rx="4" ry="3.9"/>
</g>
<g>
<polyline class="st4" points="565.8,174.4 500,174.4 500,239.1 "/>
<ellipse class="st3" cx="565" cy="173.8" rx="4" ry="3.9"/>
</g>
<g>
<line class="st4" x1="631.5" y1="173.8" x2="631.5" y2="239.1"/>
<ellipse class="st3" cx="631.5" cy="173.8" rx="4" ry="3.9"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -2,7 +2,11 @@
{% block content %} {% block content %}
<div class="row container section"> <div class="row container section">
<div class="col s12 m12 l12"> <div class="col s12 m12 l12">
<h2 class="header center-align">{{ user.username }}</h2> {% if user.first_name or user.last_name %}
<h2 class="header center-align">{{ user.first_name }} {{ user.last_name }}</h2>
{% else %}
<h2 class="header center-align">{{ user.username }}</h2>
{% endif %}
<div class="card horizontal" style="width:100%;"> <div class="card horizontal" style="width:100%;">
<div class="card-image"> <div class="card-image">
<img src="/media/{{ user.profile.icon }}"> <img src="/media/{{ user.profile.icon }}">