├── data └── .gitkeep ├── blog ├── __init__.py ├── migrations │ ├── __init__.py │ └── 0001_initial.py ├── context_processors.py ├── sitemap.py ├── managers.py ├── urls.py ├── admin.py ├── views.py ├── feeds.py ├── models.py ├── tests.py └── fixtures │ └── radpress_posts.json ├── people ├── __init__.py ├── migrations │ ├── __init__.py │ ├── 0003_auto_20150707_0943.py │ ├── 0002_auto_20150311_1220.py │ ├── 0001_initial.py │ └── 0004_auto_20191110_1009.py ├── admin.py ├── managers.py ├── urls.py ├── forms.py ├── templatetags │ └── people_extras.py ├── views.py ├── models.py └── tests.py ├── pyist ├── __init__.py ├── settings_local.py.dist ├── mixins.py ├── urls.py ├── wsgi.py └── settings.py ├── presentations ├── __init__.py ├── migrations │ ├── __init__.py │ ├── 0002_auto_20170713_2300.py │ └── 0001_initial.py ├── admin.py ├── urls.py ├── views.py ├── models.py ├── tests.py └── fixtures │ └── initial_data.json ├── static_files ├── js │ ├── main.js │ ├── html5shiv.js │ └── bootstrap.min.js ├── images │ ├── logo.png │ ├── favicon.ico │ ├── home-bg.jpeg │ ├── octocat.jpg │ ├── what-icon.png │ ├── contact-icon.png │ ├── fiber-papers.png │ ├── footer-logo.png │ ├── newsletter-icon.png │ └── logo.svg ├── fonts │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ └── fontawesome-webfont.woff2 └── css │ ├── main.css │ └── font-awesome.min.css ├── tox.ini ├── .travis.yml ├── conf ├── gunicorn.py └── nginx.conf ├── fabenv.py.dist ├── templates ├── 404.html ├── flatpages │ └── default.html ├── base_page.html ├── people │ ├── person_form.html │ └── person_list.html ├── blog │ ├── blog_detail.html │ └── partials │ │ └── disqus.html ├── djangospam │ └── cookieform.html ├── presentations │ └── presentation_list.html ├── index.html └── base.html ├── Pipfile ├── manage.py ├── LICENSE ├── README.md ├── fabfile.py ├── .gitignore └── Pipfile.lock /data/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /people/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyist/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /presentations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /people/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /presentations/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static_files/js/main.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function(){}); 2 | -------------------------------------------------------------------------------- /pyist/settings_local.py.dist: -------------------------------------------------------------------------------- 1 | from pyist.settings import * 2 | 3 | DEBUG = True 4 | -------------------------------------------------------------------------------- /static_files/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyistanbul/website/HEAD/static_files/images/logo.png -------------------------------------------------------------------------------- /static_files/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyistanbul/website/HEAD/static_files/images/favicon.ico -------------------------------------------------------------------------------- /static_files/images/home-bg.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyistanbul/website/HEAD/static_files/images/home-bg.jpeg -------------------------------------------------------------------------------- /static_files/images/octocat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyistanbul/website/HEAD/static_files/images/octocat.jpg -------------------------------------------------------------------------------- /static_files/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyistanbul/website/HEAD/static_files/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /static_files/images/what-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyistanbul/website/HEAD/static_files/images/what-icon.png -------------------------------------------------------------------------------- /static_files/images/contact-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyistanbul/website/HEAD/static_files/images/contact-icon.png -------------------------------------------------------------------------------- /static_files/images/fiber-papers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyistanbul/website/HEAD/static_files/images/fiber-papers.png -------------------------------------------------------------------------------- /static_files/images/footer-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyistanbul/website/HEAD/static_files/images/footer-logo.png -------------------------------------------------------------------------------- /people/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from .models import Person 4 | 5 | 6 | admin.site.register(Person) 7 | -------------------------------------------------------------------------------- /static_files/images/newsletter-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyistanbul/website/HEAD/static_files/images/newsletter-icon.png -------------------------------------------------------------------------------- /static_files/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyistanbul/website/HEAD/static_files/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /static_files/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyistanbul/website/HEAD/static_files/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /static_files/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyistanbul/website/HEAD/static_files/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /static_files/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyistanbul/website/HEAD/static_files/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /presentations/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from .models import Presentation 4 | 5 | 6 | admin.site.register(Presentation) 7 | -------------------------------------------------------------------------------- /blog/context_processors.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | 3 | 4 | def export_blog_settings(request): 5 | return { 6 | 'BLOG_SETTINGS': settings.BLOG, 7 | } 8 | -------------------------------------------------------------------------------- /people/managers.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class PeopleManager(models.Manager): 5 | 6 | def active(self): 7 | return self.get_queryset().filter(is_active=True) 8 | -------------------------------------------------------------------------------- /people/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from .views import PeopleView 4 | 5 | app_name = "people" 6 | 7 | urlpatterns = [ 8 | path('', PeopleView.as_view(), name='index'), 9 | ] 10 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = py36, py37, py38 3 | skipsdist = True 4 | 5 | [testenv] 6 | deps = pipenv 7 | commands = 8 | pipenv install --dev 9 | pipenv run python manage.py test --verbosity 2 10 | -------------------------------------------------------------------------------- /presentations/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from .views import PresentationsView 4 | 5 | 6 | app_name = "presentations" 7 | 8 | urlpatterns = [ 9 | path('', PresentationsView.as_view(), name='index'), 10 | ] 11 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | matrix: 3 | include: 4 | - python: 3.6 5 | env: TOXENV=py36 6 | - python: 3.7 7 | env: TOXENV=py37 8 | - python: 3.8 9 | env: TOXENV=py38 10 | install: pip install tox 11 | script: tox 12 | -------------------------------------------------------------------------------- /people/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | 3 | from .models import Person 4 | 5 | 6 | class PersonForm(forms.ModelForm): 7 | class Meta: 8 | model = Person 9 | fields = ("name", "email", "blog_link", "twitter_username", 10 | "github_username") 11 | -------------------------------------------------------------------------------- /conf/gunicorn.py: -------------------------------------------------------------------------------- 1 | import multiprocessing 2 | 3 | 4 | bind = "127.0.0.1:9009" 5 | proc_name = "pyistanbul" 6 | workers = multiprocessing.cpu_count() * 2 + 1 7 | backlog = 2048 8 | debug = False 9 | daemon = True 10 | pidfile = "/tmp/" + proc_name + ".pid" 11 | logfile = "/tmp/" + proc_name + ".log" 12 | -------------------------------------------------------------------------------- /fabenv.py.dist: -------------------------------------------------------------------------------- 1 | from fabric.api import env 2 | 3 | env.hosts = ['berkerpeksag.com'] 4 | env.host = env.hosts[0] 5 | env.user = 'wakefield' 6 | env.password = '' 7 | env.project_name = 'pyistanbul' 8 | env.domain = 'pyistanbul.org' 9 | env.root = '/home/wakefield/' 10 | env.activate = 'source venv/bin/activate' 11 | -------------------------------------------------------------------------------- /blog/sitemap.py: -------------------------------------------------------------------------------- 1 | from django.contrib.sitemaps import Sitemap 2 | 3 | from .models import Post 4 | 5 | 6 | class BlogSitemap(Sitemap): 7 | changefreq = "never" 8 | priority = 0.9 9 | 10 | def items(self): 11 | return Post.objects.active() 12 | 13 | def lastmod(self, obj): 14 | return obj.updated_at 15 | -------------------------------------------------------------------------------- /blog/managers.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class BlogManager(models.Manager): 5 | 6 | def active(self): 7 | return super(BlogManager, self).get_queryset().filter( 8 | is_published=True) 9 | 10 | def passive(self): 11 | return super(BlogManager, self).get_queryset().filter( 12 | is_published=False) 13 | -------------------------------------------------------------------------------- /templates/404.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |

Sayfa bulunamadı

5 |

6 | Eğer bu hatayı almaya devam ederseniz lütfen 7 | https://github.com/pyistanbul/website/issues/new 8 | adresini kullanarak bizi haberdar edin. 9 |

10 | {% endblock %} 11 | -------------------------------------------------------------------------------- /templates/flatpages/default.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load markitup_tags %} 3 | 4 | {% block title %}{{ flatpage.title }}{% endblock %} 5 | 6 | {% block content %} 7 |
8 |
9 |

{{ flatpage.title }}

10 |
11 | {{ flatpage.content|render_markup|safe }} 12 |
13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | name = "pypi" 3 | url = "https://pypi.org/simple" 4 | verify_ssl = true 5 | 6 | [dev-packages] 7 | 8 | [packages] 9 | django = "==3.1.7" 10 | # djangospam = "==1.1.4" 11 | django-gravatar2 = "==1.4.4" 12 | django-markitup = "==4.0.0" 13 | django-nose = "==1.4.7" 14 | gunicorn = "==20.0.4" 15 | markdown = "==3.3.4" 16 | 17 | [requires] 18 | python_version = "3.8" 19 | -------------------------------------------------------------------------------- /presentations/views.py: -------------------------------------------------------------------------------- 1 | from django.views.generic import ListView 2 | 3 | from .models import Presentation 4 | 5 | 6 | class PresentationsView(ListView): 7 | model = Presentation 8 | 9 | def get_context_data(self, **kwargs): 10 | context = super().get_context_data(**kwargs) 11 | 12 | context["page"] = "presentation" 13 | context["page_title"] = "Sunumlar" 14 | 15 | return context 16 | -------------------------------------------------------------------------------- /presentations/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class Presentation(models.Model): 5 | title = models.CharField(max_length=255) 6 | owner = models.CharField(max_length=255) 7 | date = models.DateField() 8 | link = models.URLField(blank=True, null=True) 9 | description = models.TextField(blank=True) 10 | 11 | class Meta: 12 | ordering = ['-date'] 13 | 14 | def __str__(self): 15 | return self.title 16 | -------------------------------------------------------------------------------- /blog/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from .feeds import BlogAtomFeed, BlogRssFeed 4 | from .views import BlogDetailView, BlogListView 5 | 6 | app_name = "blog" 7 | 8 | urlpatterns = [ 9 | path('', BlogListView.as_view(), name="home"), 10 | path('blog//', BlogDetailView.as_view(), name="detail"), 11 | path('feed/rss/', BlogRssFeed(), name="rss-feed"), 12 | path('feed/atom/', BlogAtomFeed(), name="blog-atom-feed"), 13 | ] 14 | -------------------------------------------------------------------------------- /templates/base_page.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block cover %} 4 |
5 |
6 |
7 |

{% if page_title %}{{ page_title }}{% endif %}

8 |
9 |
10 |
11 | {% endblock cover %} 12 | 13 | {% block content %} 14 |
15 |
16 | {% block page %} 17 | {% endblock page %} 18 |
19 |
20 | {% endblock content %} -------------------------------------------------------------------------------- /blog/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from .models import Post 4 | 5 | 6 | class BlogAdmin(admin.ModelAdmin): 7 | list_display = ("title", "slug", "is_published",) 8 | list_filter = ('is_published',) 9 | search_fields = ("title", "slug", "description",) 10 | exclude = ("author",) 11 | 12 | def save_model(self, request, obj, form, change): 13 | obj.author = request.user 14 | obj.save() 15 | 16 | admin.site.register(Post, BlogAdmin) 17 | -------------------------------------------------------------------------------- /pyist/mixins.py: -------------------------------------------------------------------------------- 1 | from django.contrib import messages 2 | from django.core.exceptions import ImproperlyConfigured 3 | 4 | 5 | class SuccessMessageMixin: 6 | success_message = None 7 | 8 | def form_valid(self, form): 9 | if not self.success_message: 10 | raise ImproperlyConfigured( 11 | 'No message to show. Provide a success_message.' 12 | ) 13 | messages.success(self.request, self.success_message) 14 | return super().form_valid(form) 15 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | settings_local_path = 'pyist/settings_local.py' 7 | settings_name = 'pyist.settings' 8 | if os.path.exists(settings_local_path): 9 | settings = settings_name + '_local' 10 | else: 11 | settings = settings_name 12 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", settings) 13 | 14 | from django.core.management import execute_from_command_line 15 | 16 | execute_from_command_line(sys.argv) 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2004 Sam Hocevar 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | -------------------------------------------------------------------------------- /people/migrations/0003_auto_20150707_0943.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.db import models, migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('people', '0002_auto_20150311_1220'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='person', 15 | name='is_active', 16 | field=models.BooleanField(default=True), 17 | preserve_default=True, 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /presentations/migrations/0002_auto_20170713_2300.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.db import models, migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('presentations', '0001_initial'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='presentation', 15 | name='link', 16 | field=models.URLField(null=True, blank=True), 17 | preserve_default=True, 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /people/templatetags/people_extras.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | from django.utils.safestring import mark_safe 3 | 4 | register = template.Library() 5 | 6 | 7 | def fontawesome(icon_name, size=""): 8 | """ 9 | Generate fontawesome syntax for HTML. 10 | 11 | Usage: 12 | 13 | {% fontawesome "iconname" %} 14 | {% fontawesome "iconname" "size" %} 15 | 16 | Size values are: lg, 2x, 3x, 4x, 5x 17 | """ 18 | if len(size) > 0: 19 | size = "fa-%s" % size 20 | result = '' % (icon_name, size) 21 | return mark_safe(result) 22 | 23 | 24 | register.simple_tag(fontawesome) 25 | -------------------------------------------------------------------------------- /people/migrations/0002_auto_20150311_1220.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.db import models, migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('people', '0001_initial'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='person', 15 | name='github_username', 16 | field=models.CharField(help_text=b'GitHub kullan\xc4\xb1c\xc4\xb1 ad\xc4\xb1n\xc4\xb1z\xc4\xb1 giriniz.', max_length=255, null=True, verbose_name=b'GitHub', blank=True), 17 | preserve_default=True, 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /people/views.py: -------------------------------------------------------------------------------- 1 | from django.urls import reverse 2 | from django.views.generic import ListView 3 | 4 | from people.forms import PersonForm 5 | from people.models import Person 6 | 7 | 8 | class PeopleView(ListView): 9 | queryset = Person.objects.active() 10 | form_class = PersonForm 11 | success_message = 'Kişi başarıyla eklendi.' 12 | 13 | def get_success_url(self): 14 | return reverse("people:index") 15 | 16 | def get_context_data(self, **kwargs): 17 | context = super().get_context_data(**kwargs) 18 | 19 | context["page"] = "people" 20 | context["page_title"] = "İnsanlar" 21 | 22 | return context 23 | -------------------------------------------------------------------------------- /templates/people/person_form.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |

Yeni kişi

5 |
6 | {% csrf_token %} 7 | {% for field in form %} 8 |
9 | {{ field.errors }} 10 | {{ field.label_tag }} 11 |
12 | {{ field }} 13 |

{{ field.help_text }}

14 |
15 |
16 | {% endfor %} 17 |
18 | 19 |
20 |
21 | 22 | {% endblock %} 23 | -------------------------------------------------------------------------------- /blog/views.py: -------------------------------------------------------------------------------- 1 | from django.views.generic import ListView 2 | from django.views.generic.detail import DetailView 3 | from django.conf import settings 4 | 5 | from .models import Post 6 | 7 | 8 | class BlogListView(ListView): 9 | template_name = 'index.html' 10 | queryset = Post.objects.active() 11 | paginate_by = settings.BLOG['LIMIT'] 12 | 13 | def get_context_data(self, **kwargs): 14 | context = super(BlogListView, self).get_context_data(**kwargs) 15 | context['page'] = 'home' 16 | return context 17 | 18 | 19 | class BlogDetailView(DetailView): 20 | template_name = "blog/blog_detail.html" 21 | queryset = Post.objects.active() 22 | -------------------------------------------------------------------------------- /conf/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | server_name ~^www\.(?P.+)$; 3 | rewrite ^ http://$domain$request_uri permanent; 4 | } 5 | 6 | server { 7 | listen 80; 8 | server_name pyistanbul.org; 9 | 10 | access_log /home/wakefield/_pyistanbul_access.log; 11 | error_log /home/wakefield/_pyistanbul_error.log; 12 | 13 | index index.html; 14 | root /home/wakefield/pyistanbul; 15 | 16 | location /static { 17 | autoindex on; 18 | root /home/wakefield/pyistanbul; 19 | } 20 | 21 | location / { 22 | proxy_pass http://127.0.0.1:9009; 23 | proxy_set_header Host $proxy_host; 24 | proxy_set_header X-Real-IP $remote_addr; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /templates/blog/blog_detail.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}{{ object.title }}{% endblock %} 4 | 5 | {% block content %} 6 |
7 |
8 | 9 |

{{ object.title }}

10 |
11 | {% autoescape off %} 12 | {{ object.description.rendered }} 13 | {% endautoescape %} 14 |
15 | 16 | {% if BLOG_SETTINGS.USE_DISQUS %} 17 |
18 |
19 | {% include "blog/partials/disqus.html" %} 20 |
21 |
22 | {% endif %} 23 | {% endblock %} -------------------------------------------------------------------------------- /templates/blog/partials/disqus.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 11 | 12 | comments powered by Disqus -------------------------------------------------------------------------------- /templates/djangospam/cookieform.html: -------------------------------------------------------------------------------- 1 | 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python Istanbul Website 2 | 3 | [![Build Status](https://travis-ci.org/pyistanbul/website.png?branch=master)](https://travis-ci.org/pyistanbul/website) 4 | 5 | ## Installation 6 | 7 | ```sh 8 | $ git clone https://github.com/pyistanbul/website.git 9 | $ cd website/ 10 | $ pipenv install 11 | $ pipenv shell 12 | $ cp pyist/settings_local.py.dist pyist/settings_local.py 13 | $ python manage.py migrate 14 | $ python manage.py runserver 15 | $ open http://127.0.0.1:8000/ 16 | ``` 17 | 18 | To run all unit tests: 19 | 20 | ```sh 21 | $ python manage.py test -v2 22 | ``` 23 | 24 | ### License 25 | 26 | Copyright © 2013 Python Istanbul 27 | 28 | This work is free. You can redistribute it and/or modify it under the 29 | terms of the Do What The Fuck You Want To Public License, Version 2, 30 | as published by Sam Hocevar. See the LICENSE file for more details. 31 | -------------------------------------------------------------------------------- /blog/feeds.py: -------------------------------------------------------------------------------- 1 | from django.contrib.syndication.views import Feed 2 | from django.utils.feedgenerator import Atom1Feed 3 | from django.conf import settings 4 | 5 | from .models import Post 6 | 7 | 8 | class BlogRssFeed(Feed): 9 | title = settings.BLOG['TITLE'] 10 | description = settings.BLOG['DESCRIPTION'] 11 | link = settings.BLOG['URL'] 12 | 13 | def items(self): 14 | return Post.objects.active()[:20] 15 | 16 | def item_description(self, post): 17 | return post.description 18 | 19 | def item_pubdate(self, post): 20 | return post.created_at 21 | 22 | def item_title(self, item): 23 | return item.title 24 | 25 | def item_link(self, item): 26 | return item.get_absolute_url() 27 | 28 | 29 | class BlogAtomFeed(BlogRssFeed): 30 | feed_type = Atom1Feed 31 | subtitle = settings.BLOG['DESCRIPTION'] 32 | -------------------------------------------------------------------------------- /presentations/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.db import models, migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ] 10 | 11 | operations = [ 12 | migrations.CreateModel( 13 | name='Presentation', 14 | fields=[ 15 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 16 | ('title', models.CharField(max_length=255)), 17 | ('owner', models.CharField(max_length=255)), 18 | ('date', models.DateField()), 19 | ('link', models.URLField()), 20 | ('description', models.TextField(blank=True)), 21 | ], 22 | options={ 23 | 'ordering': ['-date'], 24 | }, 25 | bases=(models.Model,), 26 | ), 27 | ] 28 | -------------------------------------------------------------------------------- /blog/models.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.db import models 3 | from django.urls import reverse 4 | from markitup.fields import MarkupField 5 | 6 | from .managers import BlogManager 7 | 8 | 9 | class Post(models.Model): 10 | title = models.CharField(max_length=255) 11 | slug = models.SlugField(max_length=255, unique=True) 12 | description = MarkupField() 13 | created_at = models.DateTimeField(auto_now_add=True, editable=False) 14 | updated_at = models.DateTimeField(auto_now=True, editable=False) 15 | is_published = models.BooleanField(default=True) 16 | author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) 17 | 18 | objects = BlogManager() 19 | 20 | class Meta: 21 | ordering = ["-created_at"] 22 | 23 | def __str__(self): 24 | return self.title 25 | 26 | def get_absolute_url(self): 27 | return reverse('blog:detail', args=[str(self.slug)]) 28 | -------------------------------------------------------------------------------- /pyist/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.conf.urls.static import static 3 | from django.contrib import admin 4 | from django.contrib.sitemaps.views import index, sitemap 5 | from django.urls import include, path 6 | 7 | from blog.sitemap import BlogSitemap 8 | 9 | admin.autodiscover() 10 | 11 | sitemaps = { 12 | 'blog': BlogSitemap, 13 | } 14 | 15 | urlpatterns = [ 16 | # apps 17 | path('', include('blog.urls', namespace="blog")), 18 | path('people/', include('people.urls')), 19 | path('presentations/', include('presentations.urls')), 20 | path('sitemap.xml', index, {'sitemaps': sitemaps}), 21 | # path('sitemap-(?P
.+)\.xml$', sitemap, {'sitemaps': sitemaps}), 22 | path('sitemap-
.xml', sitemap, {'sitemaps': sitemaps}), 23 | 24 | # third party apps 25 | # path("comments/", include('djangospam.cookie.urls')), 26 | 27 | # admin 28 | path('admin/', admin.site.urls), 29 | ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) 30 | -------------------------------------------------------------------------------- /people/models.py: -------------------------------------------------------------------------------- 1 | import codecs 2 | 3 | from django.db import models 4 | 5 | from .managers import PeopleManager 6 | 7 | 8 | class Person(models.Model): 9 | name = models.CharField( 10 | max_length=255, 11 | verbose_name='Ad ve Soyad', 12 | ) 13 | email = models.EmailField( 14 | max_length=255, 15 | help_text='Gravatar için gerekmektedir, sitede gözükmeyecektir.', 16 | ) 17 | blog_link = models.URLField(max_length=255, verbose_name="Blog URL") 18 | twitter_username = models.CharField( 19 | max_length=255, blank=True, 20 | null=True, verbose_name='Twitter', 21 | help_text='Twitter kullanıcı adınızı giriniz.', 22 | ) 23 | github_username = models.CharField( 24 | max_length=255, blank=True, null=True, verbose_name='GitHub', 25 | help_text='GitHub kullanıcı adınızı giriniz.', 26 | ) 27 | is_active = models.BooleanField(default=True) 28 | 29 | objects = PeopleManager() 30 | 31 | class Meta: 32 | verbose_name_plural = "People" 33 | 34 | def __str__(self): 35 | return self.name 36 | 37 | def badge(self): 38 | if codecs.encode(self.email, "rot13") == "uhfrlvanyo@tznvy.pbz": 39 | return "huseyinalbing" 40 | -------------------------------------------------------------------------------- /blog/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.db import models, migrations 4 | from django.conf import settings 5 | import markitup.fields 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='Post', 17 | fields=[ 18 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 19 | ('title', models.CharField(max_length=255)), 20 | ('slug', models.SlugField(unique=True, max_length=255)), 21 | ('description', markitup.fields.MarkupField()), 22 | ('created_at', models.DateTimeField(auto_now_add=True)), 23 | ('updated_at', models.DateTimeField(auto_now=True)), 24 | ('is_published', models.BooleanField(default=True)), 25 | ('_description_rendered', models.TextField(editable=False, blank=True)), 26 | ('author', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), 27 | ], 28 | options={ 29 | 'ordering': ['-created_at'], 30 | }, 31 | bases=(models.Model,), 32 | ), 33 | ] 34 | -------------------------------------------------------------------------------- /people/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.db import models, migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ] 10 | 11 | operations = [ 12 | migrations.CreateModel( 13 | name='Person', 14 | fields=[ 15 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 16 | ('name', models.CharField(max_length=255, verbose_name=b'Ad ve Soyad')), 17 | ('email', models.EmailField(help_text=b'Gravatar i\xc3\xa7in gerekmektedir, sitede g\xc3\xb6z\xc3\xbckmeyecektir.', max_length=255)), 18 | ('blog_link', models.URLField(max_length=255, verbose_name=b'Blog URL')), 19 | ('twitter_username', models.CharField(help_text=b'Twitter kullan\xc4\xb1c\xc4\xb1 ad\xc4\xb1n\xc4\xb1z\xc4\xb1 giriniz.', max_length=255, null=True, verbose_name=b'Twitter', blank=True)), 20 | ('github_username', models.CharField(help_text=b'Github.com kullan\xc4\xb1c\xc4\xb1 ad\xc4\xb1n\xc4\xb1z\xc4\xb1 giriniz.', max_length=255, null=True, verbose_name=b'Github', blank=True)), 21 | ('is_active', models.BooleanField(default=False)), 22 | ], 23 | options={ 24 | 'verbose_name_plural': 'People', 25 | }, 26 | bases=(models.Model,), 27 | ), 28 | ] 29 | -------------------------------------------------------------------------------- /people/migrations/0004_auto_20191110_1009.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.7 on 2019-11-10 07:09 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('people', '0003_auto_20150707_0943'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='person', 15 | name='blog_link', 16 | field=models.URLField(max_length=255, verbose_name='Blog URL'), 17 | ), 18 | migrations.AlterField( 19 | model_name='person', 20 | name='email', 21 | field=models.EmailField(help_text='Gravatar için gerekmektedir, sitede gözükmeyecektir.', max_length=255), 22 | ), 23 | migrations.AlterField( 24 | model_name='person', 25 | name='github_username', 26 | field=models.CharField(blank=True, help_text='GitHub kullanıcı adınızı giriniz.', max_length=255, null=True, verbose_name='GitHub'), 27 | ), 28 | migrations.AlterField( 29 | model_name='person', 30 | name='name', 31 | field=models.CharField(max_length=255, verbose_name='Ad ve Soyad'), 32 | ), 33 | migrations.AlterField( 34 | model_name='person', 35 | name='twitter_username', 36 | field=models.CharField(blank=True, help_text='Twitter kullanıcı adınızı giriniz.', max_length=255, null=True, verbose_name='Twitter'), 37 | ), 38 | ] 39 | -------------------------------------------------------------------------------- /pyist/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for pyist project. 3 | 4 | This module contains the WSGI application used by Django's development server 5 | and any production WSGI deployments. It should expose a module-level variable 6 | named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover 7 | this application via the ``WSGI_APPLICATION`` setting. 8 | 9 | Usually you will have the standard Django WSGI application here, but it also 10 | might make sense to replace the whole Django WSGI application with a custom one 11 | that later delegates to the Django one. For example, you could introduce WSGI 12 | middleware here, or combine a Django application with an application of another 13 | framework. 14 | 15 | """ 16 | import os 17 | 18 | # We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks 19 | # if running multiple sites in the same mod_wsgi process. To fix this, use 20 | # mod_wsgi daemon mode with each site in its own daemon process, or use 21 | # os.environ["DJANGO_SETTINGS_MODULE"] = "pyist.settings" 22 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pyist.settings") 23 | 24 | # This application object is used by any WSGI server configured to use this 25 | # file. This includes Django's development server, if the WSGI_APPLICATION 26 | # setting points here. 27 | from django.core.wsgi import get_wsgi_application 28 | application = get_wsgi_application() 29 | 30 | # Apply WSGI middleware here. 31 | # from helloworld.wsgi import HelloWorldApplication 32 | # application = HelloWorldApplication(application) 33 | -------------------------------------------------------------------------------- /presentations/tests.py: -------------------------------------------------------------------------------- 1 | from unittest import skip 2 | 3 | from django.contrib.auth.models import User 4 | from django.test import Client, TestCase 5 | from django.urls import reverse 6 | 7 | from .models import Presentation 8 | 9 | 10 | class PeopleTest(TestCase): 11 | 12 | test_data = { 13 | 'title': 'foo bar', 14 | 'owner': 'edi budu', 15 | 'link': 'http://edibudu.com', 16 | 'description': 'test description', 17 | 'date': '2012-05-15', 18 | } 19 | 20 | def setUp(self): 21 | self.tester = User.objects.create(username='tester') 22 | self.client = Client() 23 | 24 | def test_listing(self): 25 | Presentation.objects.create(**self.test_data) 26 | response = self.client.get(reverse('presentations:index')) 27 | self.assertContains(response, "foo bar") 28 | self.assertContains(response, "edibudu.com") 29 | 30 | def test_without_link(self): 31 | presentation_data = self.test_data.copy() 32 | del presentation_data['link'] 33 | p_without_link = Presentation.objects.create(**presentation_data) 34 | self.assertIsNone(p_without_link.link) 35 | 36 | # FIXME: The test should be updated for new design 37 | @skip 38 | def test_grouper(self): 39 | date = "2012-01-%s" 40 | 41 | for i in range(10, 15): 42 | data = self.test_data.copy() 43 | data["date"] = date % i 44 | Presentation.objects.create(**data) 45 | 46 | response = self.client.get(reverse("presentations:index")) 47 | 48 | for i in range(10, 15): 49 | self.assertContains(response, "%s" % date % i) 50 | -------------------------------------------------------------------------------- /people/tests.py: -------------------------------------------------------------------------------- 1 | from unittest import skip 2 | 3 | from django.contrib.auth.models import User 4 | from django.test import Client, TestCase 5 | from django.urls import reverse 6 | 7 | from .models import Person 8 | 9 | 10 | class PeopleTest(TestCase): 11 | test_data = { 12 | 'name': 'edi budu', 13 | 'email': 'edi@budu.com', 14 | 'blog_link': 'http://edibudu.com', 15 | 'twitter_username': 'edibudu', 16 | 'github_username': 'edicat', 17 | 'is_active': True, 18 | } 19 | 20 | def setUp(self): 21 | self.tester = User.objects.create(username='tester') 22 | self.client = Client() 23 | 24 | @skip 25 | def test_create(self): 26 | response = self.client.post(reverse('people:new'), self.test_data) 27 | self.assertRedirects(response, reverse('people:index')) 28 | self.assertTrue(Person.objects.exists()) 29 | 30 | person = Person.objects.get() 31 | self.assertEqual(person.name, 'edi budu') 32 | self.assertEqual(person.email, 'edi@budu.com') 33 | self.assertEqual(person.blog_link, 'http://edibudu.com') 34 | self.assertEqual(person.twitter_username, 'edibudu') 35 | self.assertEqual(person.github_username, 'edicat') 36 | 37 | def test_listing(self): 38 | Person.objects.create(**self.test_data) 39 | response = self.client.get(reverse('people:index')) 40 | self.assertContains(response, "edi budu") 41 | 42 | def test_active_listing(self): 43 | data = self.test_data.copy() 44 | data["is_active"] = False 45 | Person.objects.create(**data) 46 | 47 | response = self.client.get(reverse("people:index")) 48 | 49 | self.assertNotContains(response, "edi budu") 50 | -------------------------------------------------------------------------------- /static_files/js/html5shiv.js: -------------------------------------------------------------------------------- 1 | (function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag(); 2 | a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/\w+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x"; 3 | c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode|| 4 | "undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);if(g)return a.createDocumentFragment(); 5 | for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d 6 |
7 |
8 | {% regroup presentation_list by date as presentations %} 9 | {% for date in presentations %} 10 |
11 |
12 |
Pyİstanbul 11 Temmuz Etkinliği
13 | 36 |
37 | {% for presentation in date.list %} 38 |
39 | 40 |
{{ presentation.title }}
41 |
42 |
{{ presentation.owner }}
43 |
44 | {% endfor %} 45 |
46 |
47 |
48 | {% endfor %} 49 |
50 |
51 | 52 | {% endblock %} 53 | -------------------------------------------------------------------------------- /fabfile.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from contextlib import contextmanager 4 | 5 | from fabric.api import cd, env, local, run, sudo, prefix 6 | 7 | try: 8 | from fabenv import env 9 | except ImportError: 10 | msg = "Kurulum için lütfen README.md belgesini okuyun." 11 | raise RuntimeError(msg) 12 | 13 | 14 | @contextmanager 15 | def venv(): 16 | with cd('%(root)s%(project_name)s' % env), prefix(env.activate): 17 | yield 18 | 19 | 20 | def deploy(): 21 | """Deploy the latest version.""" 22 | with venv(): 23 | run('git pull') 24 | update_dependencies() 25 | run('python manage.py migrate') 26 | update_static() 27 | restart() 28 | restart_nginx() 29 | 30 | 31 | def start(): 32 | with venv(): 33 | run('gunicorn -c conf/gunicorn.py pyist.wsgi:application') 34 | 35 | restart_nginx() 36 | 37 | 38 | def restart(): 39 | with venv(): 40 | sudo('sudo kill -HUP `cat /tmp/' + env.project_name + '.pid`') 41 | 42 | 43 | def restart_nginx(): 44 | """Restart the nginx process.""" 45 | sudo('/etc/init.d/nginx restart') 46 | 47 | 48 | def update_dependencies(): 49 | """Update requirements remotely.""" 50 | with venv(): 51 | run('pip install -r conf/requirements.txt') 52 | 53 | 54 | def update_nginx_conf(): 55 | sudo('rm /etc/nginx/sites-enabled/' + env.domain) 56 | sudo('ln -s /home/wakefield/pyistanbul/conf/nginx.conf /etc/nginx/sites-enabled/' + env.domain) 57 | restart_nginx() 58 | 59 | 60 | def update_static(): 61 | """Update static files.""" 62 | with venv(): 63 | sudo('python manage.py collectstatic --clear --noinput') 64 | 65 | 66 | def setup(): 67 | """Configure basic tools.""" 68 | with cd(env.root): 69 | run('git clone git://github.com/pyistanbul/website.git ' + env.project_name) 70 | 71 | with cd('%(root)s%(project_name)s' % env): 72 | run('virtualenv venv') 73 | 74 | with venv(): 75 | run('pip install -r conf/requirements.txt') 76 | 77 | update_nginx_conf() 78 | update_static() 79 | start() 80 | 81 | 82 | def setup_vm(): 83 | """Setup the VM.""" 84 | sudo('apt-get update && apt-get upgrade && apt-get install git-core ' 85 | 'python-setuptools python-pip python-dev build-essential ' 86 | 'nginx curl libcurl3') 87 | sudo('pip install virtualenv') 88 | 89 | 90 | def clean(): 91 | """Clean the current setup.""" 92 | with cd(env.root): 93 | sudo('rm -r %s/' % env.project_name) 94 | sudo('rm /etc/nginx/sites-enabled/' + env.domain) 95 | 96 | 97 | def clean_pyc(): 98 | """Remove all .pyc files.""" 99 | local('find . -name "*.pyc" -exec rm {} \;') 100 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Based on https://github.com/github/gitignore/blob/14f8a8b4c51ecc00b18905a95c117954e6c77b9d/Python.gitignore 2 | 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | *.py[cod] 6 | *$py.class 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | build/ 14 | develop-eggs/ 15 | dist/ 16 | downloads/ 17 | eggs/ 18 | .eggs/ 19 | lib/ 20 | lib64/ 21 | parts/ 22 | sdist/ 23 | var/ 24 | wheels/ 25 | share/python-wheels/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | MANIFEST 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .nox/ 45 | .coverage 46 | .coverage.* 47 | .cache 48 | nosetests.xml 49 | coverage.xml 50 | *.cover 51 | *.py,cover 52 | .hypothesis/ 53 | .pytest_cache/ 54 | cover/ 55 | 56 | # Translations 57 | *.mo 58 | *.pot 59 | 60 | # Django stuff: 61 | *.log 62 | local_settings.py 63 | settings_local.py 64 | *.sqlite 65 | *.db 66 | db.sqlite3 67 | db.sqlite3-journal 68 | fabenv.py 69 | static/ 70 | 71 | 72 | # Flask stuff: 73 | instance/ 74 | .webassets-cache 75 | 76 | # Scrapy stuff: 77 | .scrapy 78 | 79 | # Sphinx documentation 80 | docs/_build/ 81 | 82 | # PyBuilder 83 | .pybuilder/ 84 | target/ 85 | 86 | # Jupyter Notebook 87 | .ipynb_checkpoints 88 | 89 | # IPython 90 | profile_default/ 91 | ipython_config.py 92 | 93 | # pyenv 94 | # For a library or package, you might want to ignore these files since the code is 95 | # intended to run in multiple environments; otherwise, check them in: 96 | # .python-version 97 | 98 | # pipenv 99 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 100 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 101 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 102 | # install all needed dependencies. 103 | #Pipfile.lock 104 | 105 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 106 | __pypackages__/ 107 | 108 | # Celery stuff 109 | celerybeat-schedule 110 | celerybeat.pid 111 | 112 | # SageMath parsed files 113 | *.sage.py 114 | 115 | # Environments 116 | .env 117 | .venv 118 | env/ 119 | venv/ 120 | ENV/ 121 | env.bak/ 122 | venv.bak/ 123 | 124 | # Spyder project settings 125 | .spyderproject 126 | .spyproject 127 | 128 | # Rope project settings 129 | .ropeproject 130 | 131 | # mkdocs documentation 132 | /site 133 | 134 | # mypy 135 | .mypy_cache/ 136 | .dmypy.json 137 | dmypy.json 138 | 139 | # Pyre type checker 140 | .pyre/ 141 | 142 | # pytype static type analyzer 143 | .pytype/ 144 | 145 | # Cython debug symbols 146 | cython_debug/ 147 | 148 | # Editors 149 | .idea 150 | *~ 151 | 152 | # Mac OS 153 | .DS_Store 154 | -------------------------------------------------------------------------------- /blog/tests.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth.models import User 2 | from django.test import TestCase 3 | 4 | from .models import Post 5 | 6 | 7 | class PostModelTest(TestCase): 8 | @classmethod 9 | def setUpTestData(cls): 10 | # FIXME: Replace with model factory 11 | user = User.objects.create( 12 | username="testuser", 13 | password="123456", 14 | ) 15 | 16 | # FIXME: Replace with model factory 17 | Post.objects.create( 18 | author=user, 19 | title="Hello Blog", 20 | slug="hello-blog", 21 | description="First Blog Post Hede" 22 | ) 23 | 24 | def test_get_absolute_url(self): 25 | post = Post.objects.get(id=1) 26 | self.assertEquals(post.get_absolute_url(), '/blog/hello-blog/') 27 | 28 | def test_title_max_length(self): 29 | post = Post.objects.get(id=1) 30 | max_length = post._meta.get_field('title').max_length 31 | self.assertEquals(max_length, 255) 32 | 33 | def test_slug_max_length(self): 34 | post = Post.objects.get(id=1) 35 | max_length = post._meta.get_field('slug').max_length 36 | self.assertEquals(max_length, 255) 37 | 38 | 39 | # class PostViewTest(TestCase): 40 | # @classmethod 41 | # def setUpTestData(cls): 42 | # test_user = User.objects.create(username='testuser', password='123456') 43 | # test_user.save() 44 | 45 | # number_of_posts = 10 46 | # for post_num in range(number_of_posts): 47 | # Post.objects.create(author=test_user, 48 | # title="Hello Blog %s" % post_num, 49 | # slug="hello-blog-%s" % post_num, 50 | # description="First Blog Post %s" % post_num) 51 | 52 | # def test_detail(self): 53 | # response = self.client.get(self.post.get_absolute_url()) 54 | # self.assertContains(response, self.post.slug) 55 | 56 | 57 | 58 | # class PostTest(TestCase): 59 | 60 | # dummy_data = { 61 | # 'title': 'Hello Blog', 62 | # 'slug': 'hello-blog', 63 | # 'description': 'First Blog Post Blog', 64 | # } 65 | 66 | # def setUp(self): 67 | # self.user = User.objects.create_user( 68 | # username='testpyistanbul', password='123456') 69 | # self.post = Post.objects.create( 70 | # author=self.user, **self.dummy_data) 71 | # self.client = Client() 72 | 73 | # def test_detail(self): 74 | # response = self.client.get(self.post.get_absolute_url()) 75 | # print("=================") 76 | # print(response) 77 | # print("=================") 78 | # self.assertContains(response, self.dummy_data['slug']) 79 | 80 | # def test_list(self): 81 | # response = self.client.get(reverse('blog:home')) 82 | # self.assertContains(response, self.dummy_data['title']) 83 | 84 | # def test_valid(self): 85 | # response = self.client.get(reverse('blog:detail', args=['hello-blog'])) 86 | # self.assertEqual(response.status_code, 200) 87 | 88 | # def test_invalid_detail(self): 89 | # response = self.client.get( 90 | # reverse('blog:detail', args=['test-test'])) 91 | # self.assertEqual(response.status_code, 404) 92 | -------------------------------------------------------------------------------- /templates/people/person_list.html: -------------------------------------------------------------------------------- 1 | {% extends "base_page.html" %} 2 | 3 | {% load gravatar %} 4 | 5 | {% block page %} 6 |
7 |
8 | {% for person in person_list %} 9 |
10 | {% gravatar person.email 100 %} 11 |
{{ person.name }}
12 |
software developer @adphorus
13 |
    14 | {% if person.twitter_username %} 15 |
  • 16 | 17 |
  • 18 | {% endif %} 19 | {% if person.github_username %} 20 |
  • 21 | 22 |
  • 23 | {% endif %} 24 | {% if person.blog_link %} 25 |
  • 26 | 27 |
  • 28 | {% endif %} 29 |
30 |
31 | {% endfor %} 32 |
33 |
34 |
Yeni Kişi Ekle
35 |
36 |
37 |
38 | 39 | 40 | 78 | {% endblock %} 79 | -------------------------------------------------------------------------------- /Pipfile.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "hash": { 4 | "sha256": "763697b355e7493df66d8debca5ea7dffd598a75ea0cf9e8de5ae754de5a7b67" 5 | }, 6 | "pipfile-spec": 6, 7 | "requires": { 8 | "python_version": "3.8" 9 | }, 10 | "sources": [ 11 | { 12 | "name": "pypi", 13 | "url": "https://pypi.org/simple", 14 | "verify_ssl": true 15 | } 16 | ] 17 | }, 18 | "default": { 19 | "asgiref": { 20 | "hashes": [ 21 | "sha256:34103fa20270d8843a66e5df18547d2e8139534d23e3beffe96647c65ddffd4d", 22 | "sha256:c62b616b226d6c2e927b0225f8101f9e2cca08112cff98839ca6726c129ff9e0" 23 | ], 24 | "index": "pypi", 25 | "version": "==3.3.2" 26 | }, 27 | "django": { 28 | "hashes": [ 29 | "sha256:32ce792ee9b6a0cbbec340123e229ac9f765dff8c2a4ae9247a14b2ba3a365a7", 30 | "sha256:baf099db36ad31f970775d0be5587cc58a6256a6771a44eb795b554d45f211b8" 31 | ], 32 | "index": "pypi", 33 | "version": "==3.1.7" 34 | }, 35 | "django-gravatar2": { 36 | "hashes": [ 37 | "sha256:545a6c2c5c624c7635dec29c7bc0be1a2cb89c9b8821af8616ae9838827cc35b", 38 | "sha256:c813280967511ced93eea0359f60e5369c35b3311efe565c3e5d4ab35c10c9ee" 39 | ], 40 | "index": "pypi", 41 | "version": "==1.4.4" 42 | }, 43 | "django-markitup": { 44 | "hashes": [ 45 | "sha256:938e202f66b3b6ab50af6b3f002638372520869d15037f5a3a67758ebce4fca0", 46 | "sha256:9e2ebd537ecd8b77b94a0f0ef30ec9f87006f3bd12711848136d4bf3166112af" 47 | ], 48 | "index": "pypi", 49 | "version": "==4.0.0" 50 | }, 51 | "django-nose": { 52 | "hashes": [ 53 | "sha256:304adc447ee35b889b733d7106004f98aa401d8387ddcada5d4f2239d86790a9", 54 | "sha256:a4885cd002d65fd2de96e2bb2563ef477c3fbe207009360c015fca5c3b5561b7" 55 | ], 56 | "index": "pypi", 57 | "version": "==1.4.7" 58 | }, 59 | "gunicorn": { 60 | "hashes": [ 61 | "sha256:1904bb2b8a43658807108d59c3f3d56c2b6121a701161de0ddf9ad140073c626", 62 | "sha256:cd4a810dd51bf497552cf3f863b575dabd73d6ad6a91075b65936b151cbf4f9c" 63 | ], 64 | "index": "pypi", 65 | "version": "==20.0.4" 66 | }, 67 | "markdown": { 68 | "hashes": [ 69 | "sha256:31b5b491868dcc87d6c24b7e3d19a0d730d59d3e46f4eea6430a321bed387a49", 70 | "sha256:96c3ba1261de2f7547b46a00ea8463832c921d3f9d6aba3f255a6f71386db20c" 71 | ], 72 | "index": "pypi", 73 | "version": "==3.3.4" 74 | }, 75 | "nose": { 76 | "hashes": [ 77 | "sha256:9ff7c6cc443f8c51994b34a667bbcf45afd6d945be7477b52e97516fd17c53ac", 78 | "sha256:dadcddc0aefbf99eea214e0f1232b94f2fa9bd98fa8353711dacb112bfcbbb2a", 79 | "sha256:f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98" 80 | ], 81 | "version": "==1.3.7" 82 | }, 83 | "pytz": { 84 | "hashes": [ 85 | "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da", 86 | "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798" 87 | ], 88 | "version": "==2021.1" 89 | }, 90 | "sqlparse": { 91 | "hashes": [ 92 | "sha256:017cde379adbd6a1f15a61873f43e8274179378e95ef3fede90b5aa64d304ed0", 93 | "sha256:0f91fd2e829c44362cbcfab3e9ae12e22badaa8a29ad5ff599f9ec109f0454e8" 94 | ], 95 | "version": "==0.4.1" 96 | } 97 | }, 98 | "develop": {} 99 | } 100 | -------------------------------------------------------------------------------- /static_files/images/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /pyist/settings.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | PROJECT_PATH = os.path.abspath(os.getcwd()) 4 | 5 | DEBUG = False 6 | TEMPLATE_DEBUG = DEBUG 7 | 8 | ADMINS = ( 9 | ('Fatih Erikli', 'fatiherikli@gmail.com'), 10 | ('Berker Peksag', 'berkerpeksag@gmail.com'), 11 | ) 12 | 13 | MANAGERS = ADMINS 14 | ALLOWED_HOSTS = [ 15 | '127.0.0.1', 16 | ] 17 | TIME_ZONE = 'Europe/Istanbul' 18 | LANGUAGE_CODE = 'tr-tr' 19 | SITE_ID = 1 20 | 21 | USE_I18N = True 22 | USE_L10N = True 23 | USE_TZ = True 24 | 25 | MEDIA_ROOT = '' 26 | MEDIA_URL = '' 27 | STATIC_ROOT = '{:s}/static/'.format(PROJECT_PATH) 28 | STATIC_URL = '/static/' 29 | 30 | STATICFILES_DIRS = ( 31 | '{:s}/static_files/'.format(PROJECT_PATH), 32 | ) 33 | 34 | STATICFILES_FINDERS = ( 35 | 'django.contrib.staticfiles.finders.FileSystemFinder', 36 | 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 37 | ) 38 | 39 | SECRET_KEY = '#1f*6@=e@*7t1yk_!gef=jn!pc5#mv_%)=8__y8*gi0&0t7=u(' 40 | 41 | MIDDLEWARE = ( 42 | 'django.middleware.common.CommonMiddleware', 43 | 'django.contrib.sessions.middleware.SessionMiddleware', 44 | 'django.middleware.csrf.CsrfViewMiddleware', 45 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 46 | 'django.contrib.messages.middleware.MessageMiddleware', 47 | # 'djangospam.cookie.middleware.SpamCookieMiddleware', 48 | 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware', 49 | ) 50 | 51 | ROOT_URLCONF = 'pyist.urls' 52 | 53 | 54 | WSGI_APPLICATION = 'pyist.wsgi.application' 55 | 56 | 57 | TEMPLATES = [ 58 | { 59 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 60 | 'DIRS': [os.path.join(PROJECT_PATH, 'templates')], 61 | 'APP_DIRS': True, 62 | 'OPTIONS': { 63 | 'context_processors': [ 64 | 'django.template.context_processors.debug', 65 | 'django.template.context_processors.request', 66 | 'django.contrib.auth.context_processors.auth', 67 | 'django.contrib.messages.context_processors.messages', 68 | ], 69 | }, 70 | }, 71 | ] 72 | 73 | ROOT_URLCONF = 'pyist.urls' 74 | 75 | 76 | WSGI_APPLICATION = 'pyist.wsgi.application' 77 | 78 | 79 | TEMPLATES = [ 80 | { 81 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 82 | 'DIRS': [os.path.join(PROJECT_PATH, 'templates')], 83 | 'APP_DIRS': True, 84 | 'OPTIONS': { 85 | 'context_processors': [ 86 | 'django.template.context_processors.debug', 87 | 'django.template.context_processors.request', 88 | 'django.contrib.auth.context_processors.auth', 89 | 'django.contrib.messages.context_processors.messages', 90 | ], 91 | }, 92 | }, 93 | ] 94 | 95 | INSTALLED_APPS = ( 96 | 'django.contrib.auth', 97 | 'django.contrib.contenttypes', 98 | 'django.contrib.sessions', 99 | 'django.contrib.sites', 100 | 'django.contrib.messages', 101 | 'django.contrib.staticfiles', 102 | 'django.contrib.admin', 103 | 'django.contrib.flatpages', 104 | 'django.contrib.sitemaps', 105 | 106 | 'django_gravatar', 107 | 'markitup', 108 | 'nose', 109 | 110 | 'people', 111 | 'presentations', 112 | 'blog', 113 | ) 114 | 115 | LOGGING = { 116 | 'version': 1, 117 | 'disable_existing_loggers': False, 118 | 'filters': { 119 | 'require_debug_false': { 120 | '()': 'django.utils.log.RequireDebugFalse' 121 | } 122 | }, 123 | 'handlers': { 124 | 'mail_admins': { 125 | 'level': 'ERROR', 126 | 'filters': ['require_debug_false'], 127 | 'class': 'django.utils.log.AdminEmailHandler' 128 | } 129 | }, 130 | 'loggers': { 131 | 'django.request': { 132 | 'handlers': ['mail_admins'], 133 | 'level': 'ERROR', 134 | 'propagate': True, 135 | }, 136 | } 137 | } 138 | 139 | # Database Settings 140 | DATABASES = { 141 | 'default': { 142 | 'ENGINE': 'django.db.backends.sqlite3', 143 | 'NAME': '{:s}/data/db.sqlite'.format(PROJECT_PATH), 144 | 'USER': '', 145 | 'PASSWORD': '', 146 | 'HOST': '', 147 | 'PORT': '', 148 | } 149 | } 150 | 151 | # Markitup Settings 152 | MARKITUP_SET = 'markitup/sets/markdown' 153 | MARKITUP_FILTER = ('markdown.markdown', {'safe_mode': False}) 154 | 155 | # Blog Settings 156 | 157 | BLOG = { 158 | 'TITLE': 'Python İstanbul', 159 | 'DESCRIPTION': 'Python İstanbul Günlüğü', 160 | 'LIMIT': 5, 161 | 'URL': 'http://pyistanbul.org/', 162 | 'DISQUS_USERNAME': 'pyistanbul', 163 | 'USE_DISQUS': False, 164 | } 165 | 166 | # Djangospam Settings 167 | # DJANGOSPAM_COOKIE_KEY = 'argumentclinic' 168 | # DJANGOSPAM_LOG = 'spam.log' 169 | 170 | # Nose Settings 171 | TEST_RUNNER = 'django_nose.NoseTestSuiteRunner' 172 | -------------------------------------------------------------------------------- /presentations/fixtures/initial_data.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "pk": 1, 4 | "model": "presentations.presentation", 5 | "fields": { 6 | "owner": "Aybars Badur, Cenk Alt\u0131", 7 | "date": "2012-11-24", 8 | "link": "https://github.com/pyistanbul/presentations/tree/master/putio-presentation", 9 | "description": " ", 10 | "title": "Put.io'nun Python'a Ge\u00e7i\u015f Hikayesi" 11 | } 12 | }, 13 | { 14 | "pk": 2, 15 | "model": "presentations.presentation", 16 | "fields": { 17 | "owner": "Cihan Okyay", 18 | "date": "2012-11-24", 19 | "link": "https://github.com/pyistanbul/presentations/tree/master/nasil-calisiyorum", 20 | "description": " ", 21 | "title": "Nas\u0131l \u00c7al\u0131\u015f\u0131yorum" 22 | } 23 | }, 24 | { 25 | "pk": 3, 26 | "model": "presentations.presentation", 27 | "fields": { 28 | "owner": "Alper Kanat", 29 | "date": "2012-11-24", 30 | "link": "https://github.com/pyistanbul/presentations/tree/master/django-301-presentation", 31 | "description": " ", 32 | "title": "Django 301" 33 | } 34 | }, 35 | { 36 | "pk": 4, 37 | "model": "presentations.presentation", 38 | "fields": { 39 | "owner": "Fatih Erikli", 40 | "date": "2012-11-24", 41 | "link": "https://github.com/pyistanbul/presentations/tree/master/django-orm-optimization", 42 | "description": " ", 43 | "title": "Django ORM Optimizasyonu" 44 | } 45 | }, 46 | { 47 | "pk": 5, 48 | "model": "presentations.presentation", 49 | "fields": { 50 | "owner": "Burak Yi\u011fit Kaya", 51 | "date": "2012-06-23", 52 | "link": "https://github.com/pyistanbul/presentations/tree/master/meta-programming-presentation", 53 | "description": " ", 54 | "title": "Python ile Meta Programlama" 55 | } 56 | }, 57 | { 58 | "pk": 6, 59 | "model": "presentations.presentation", 60 | "fields": { 61 | "owner": "Berker Peksa\u011f", 62 | "date": "2012-05-26", 63 | "link": "https://github.com/pyistanbul/presentations/tree/master/pypy-presentation", 64 | "description": " ", 65 | "title": "PyPy 101" 66 | } 67 | }, 68 | { 69 | "pk": 7, 70 | "model": "presentations.presentation", 71 | "fields": { 72 | "owner": "Fatih Erikli", 73 | "date": "2012-05-26", 74 | "link": "https://github.com/pyistanbul/presentations/tree/master/celery-presentation", 75 | "description": " ", 76 | "title": "Celery ve RabbitMQ ile Da\u011f\u0131t\u0131lm\u0131\u015f \u0130\u015fler" 77 | } 78 | }, 79 | { 80 | "pk": 8, 81 | "model": "presentations.presentation", 82 | "fields": { 83 | "owner": "Taylan Pin\u00e7e", 84 | "date": "2012-03-25", 85 | "link": "https://github.com/pyistanbul/presentations/tree/master/haystack-solr-presentation", 86 | "description": " ", 87 | "title": "Django'da Haystack + Apache Solr" 88 | } 89 | }, 90 | { 91 | "pk": 9, 92 | "model": "presentations.presentation", 93 | "fields": { 94 | "owner": "Muhammet S. Ayd\u0131n", 95 | "date": "2010-12-12", 96 | "link": "https://github.com/pyistanbul/presentations/tree/master/qooxdoo-presentation", 97 | "description": " ", 98 | "title": "Qooxdoo" 99 | } 100 | }, 101 | { 102 | "pk": 10, 103 | "model": "presentations.presentation", 104 | "fields": { 105 | "owner": "Osman Y\u00fcksel", 106 | "date": "2012-08-08", 107 | "link": "https://github.com/pyistanbul/presentations/tree/master/tornado-presentation", 108 | "description": " ", 109 | "title": "Tornado" 110 | } 111 | }, 112 | { 113 | "pk": 11, 114 | "model": "presentations.presentation", 115 | "fields": { 116 | "owner": "Atamert \u00d6l\u00e7gen", 117 | "date": "2010-08-07", 118 | "link": "https://github.com/pyistanbul/presentations/tree/master/introduction-to-rest-presentation", 119 | "description": " ", 120 | "title": "reST'e Giri\u015f" 121 | } 122 | }, 123 | { 124 | "pk": 12, 125 | "model": "presentations.presentation", 126 | "fields": { 127 | "owner": "Metin Amiroff", 128 | "date": "2010-06-13", 129 | "link": "https://github.com/pyistanbul/presentations/tree/master/python-zen-presentation", 130 | "description": " ", 131 | "title": "Python Zen'i" 132 | } 133 | }, 134 | { 135 | "pk": 13, 136 | "model": "presentations.presentation", 137 | "fields": { 138 | "owner": "Atamert \u00d6l\u00e7gen", 139 | "date": "2012-05-09", 140 | "link": "https://github.com/pyistanbul/presentations/tree/master/python-imaging-presentation", 141 | "description": " ", 142 | "title": "Python-Imaging ile Temel \u0130\u015flemler" 143 | } 144 | } 145 | ] 146 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 |
6 |
7 | 8 | 12 | 20 |
E-posta listemize başarıyla kaydoldunuz.
21 |
22 |
23 | 24 | 110 | 111 | {% endblock %} 112 | -------------------------------------------------------------------------------- /templates/base.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | 4 | 5 | 6 | 7 | 8 | {% block title %}{{ BLOG_SETTINGS.TITLE }}{% endblock %} 9 | {% if page_title %}— {{ page_title }}{% endif %} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | {% block head %} 28 | {% endblock head %} 29 | 30 | 31 | 41 |
42 |
43 |
44 |
45 |
Nedir?
46 |

İstanbul'daki Python programcıları topluluğudur. Eğer Python ilginizi çekiyorsa siz de bu topluluğa katılabilirsiniz.

47 |
48 |
49 |
Nasıl iletişim kurabilirim?
50 |

Her gün Freenode'daki #pyistanbul kanalında buluşuyoruz.

51 |
52 |
53 |
Desteğe ihtiyacım var
54 |

IRC'de ya da python-istanbul e-posta listesinde sorularınızı sorabilirsiniz.

55 |
56 |
57 |
58 |
59 |
60 | 81 |
82 | 83 | {% block cover %} 84 | {% endblock %} 85 | 86 | {% block content %} 87 | 88 | {% endblock content %} 89 | 90 |
91 |
92 |
93 |
94 |
NEWSLETTER
95 |
96 |
97 | 98 |
99 | 100 |
101 |
102 |
103 |
GITHUB
104 | pyistanbul 105 |
106 |
107 |
CONNECT WITH US
108 |
109 |
110 | 111 |
112 |
113 | 114 | 115 | 116 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /blog/fixtures/radpress_posts.json: -------------------------------------------------------------------------------- 1 | [{"pk": 1, "model": "blog.post", "fields": {"title": "Python \u0130stanbul web sitesi yenilendi", "created_at": "2013-04-28T16:34:48.494Z", "author": 1, "updated_at": "2013-12-02T19:52:08.974Z", "description": "Uzun s\u00fcredir Python \u0130stanbul web sitesi yay\u0131nda de\u011fildi. Bu haftasonu Python Istanbul i\u00e7in basit bir web sitesi haz\u0131rlad\u0131k ve yay\u0131nlad\u0131k. \u015eu an bu blog yaz\u0131s\u0131n\u0131 yeni site \u00fczerinden okuyorsunuz :)\r\n\r\nArt\u0131k yeni sitede bir blogumuz var. Bu blog'da etkinlikler hakk\u0131nda duyurular\u0131 ve etkinlik sonralar\u0131ndaki kritikler olacak. Blog i\u00e7in bir Django uygulamas\u0131 olan [G\u00f6kmen G\u00f6rgen](http://gokmengorgen.net)'in geli\u015ftirdigi [Radpress](https://github.com/gkmngrgn/radpress>)'i kullan\u0131yoruz.\r\n\r\nSitede blog d\u0131\u015f\u0131nda insanlar, sunumlar ve i\u015f ilanlar\u0131 bulunmaktad\u0131r. E\u011fer Python ile u\u011fra\u015f\u0131yorsan\u0131z kendinizi insanlar b\u00f6l\u00fcm\u00fcne ekleyebilirsiniz. Ayn\u0131 \u015fekilde duyurmak istedi\u011finiz bir i\u015f ilan\u0131 varsa bunu da i\u015f ilanlar\u0131 b\u00f6l\u00fcm\u00fcnden bildirebilirsiniz.\r\n\r\nWeb sitesi Github \u00fczerinden a\u00e7\u0131k bir \u015fekilde geli\u015ftirilmektedir. Eklemek ya da de\u011fi\u015ftirmek istedi\u011finiz bir \u015fey olursa testleri \u00e7al\u0131\u015ft\u0131r\u0131p her \u015feyin yolunda gitti\u011finden emin olduktan sonra pull request g\u00f6nderebilirsiniz.\r\n\r\n\r\n[Github deposuna ula\u015fmak i\u00e7in t\u0131klay\u0131n](http://github.com/pyistanbul/website>).", "slug": "python-istanbul-web-sitesi-yenilendi", "is_published": true}}, {"pk": 2, "model": "blog.post", "fields": {"title": "Py\u0130stanbul 25 Ocak Etkinli\u011fi", "created_at": "2013-11-29T17:03:23.340Z", "author": 2, "updated_at": "2013-12-02T19:49:57.504Z", "description": "En son ge\u00e7en y\u0131l 24 Kas\u0131m'da d\u00fczenledi\u011fimiz *sunumlu* Python \u0130stanbul etkinli\u011finin ard\u0131ndan 25 Ocak'da 2014 y\u0131l\u0131n\u0131n ilk etkinli\u011fini [Hipo](http://hipo.biz/) ofisinde d\u00fczenleyece\u011fiz.\r\n\r\nE\u011fer sunum yapmak istiyorsan\u0131z [listemize](https://groups.google.com/forum/?fromgroups#!forum/python-istanbul) kay\u0131t olup konu\u015fmak istedi\u011finiz konu hakk\u0131nda k\u0131saca bilgi vermeniz yeterli. \u015eimdiye kadar \u00f6nerilen sunum konular\u0131 g\u00f6rmek i\u00e7in yine listemizdeki [iletiye](https://groups.google.com/forum/?fromgroups#!topic/python-istanbul/-klSzaGD4vg) bakabilirsiniz.\r\n\r\n### Etkinlik Bilgileri\r\n\r\n* Tarih: 25 Ocak 2014 Cumartesi\r\n* Saat: 10:00\r\n* Adres: Hipo \u0130stanbul ofisi, Asmal\u0131 Mescit Mh. Yemenici Abd\u00fcllatif Sk. No: 9 D: 3 Beyo\u011flu\r\n* Adres tarifi: Taksim'den en kolay ula\u015f\u0131m yolu metro ile \u015ei\u015fhane istasyonunda indikten sonra, Me\u015frutiyet Caddesi \u00e7\u0131k\u0131\u015f\u0131n\u0131 kullanmak. Taksim y\u00f6n\u00fcnde y\u00fcr\u00fcrken sa\u011f taraftaki \u00fc\u00e7\u00fcnc\u00fc sokaktaki(Yemenici Abdullatif Sokak) 9 numaral\u0131 pembe bina.", "slug": "pyistanbul-25-ocak-etkinligi", "is_published": true}}, {"pk": 3, "model": "blog.post", "fields": {"title": "Py\u0130stanbul 8 \u015eubat Etkinli\u011fi", "created_at": "2014-01-23T11:18:46.035Z", "author": 2, "updated_at": "2014-06-05T22:42:55.841Z", "description": "Daha \u00f6nce 25 Ocak olarak [belirledi\u011fimiz](http://pyistanbul.org/blog/pyistanbul-25-ocak-etkinligi) etkinlik tarihini A\u00e7\u0131k\u00f6\u011fretim s\u0131navlar\u0131 nedeniyle 8 \u015eubat Cumartesi g\u00fcn\u00fcne erteledik.\r\n\r\n### Etkinlik Program\u0131\r\n\r\n* **10:00-10:30:** Tan\u0131\u015fma\r\n* **10:30-11:10:** SQLAlchemy'e Giri\u015f, *Muhammet S. Ayd\u0131n*\r\n* **11:15-11:55:** Flask ile Uygulama Geli\u015ftirmeye Giri\u015f, *\u00d6zg\u00fcr Odaba\u015f\u0131*\r\n* **12:00-13:00:** \u00d6\u011fle aras\u0131\r\n* **13:15-13:55:** Lettuce ile Behaviour Driven Development, *Fatih Erikli*\r\n* **14:00-14:40:** Graphite ve Statsd ile Monitoringe Giri\u015f, *Aybars Badur*\r\n\r\n![https://www.eventbrite.com/e/python-istanbul-8-subat-etkinligi-tickets-10522758855?ref=ebtn](https://www.eventbrite.com/custombutton?eid=10839807155)\r\n\r\n\r\n### Etkinlik Bilgileri\r\n\r\n* **Tarih:** 8 \u015eubat 2014 Cumartesi\r\n* **Saat:** 10:00\r\n* **Adres:** Hipo \u0130stanbul ofisi, Asmal\u0131 Mescit Mh. Yemenici Abd\u00fcllatif Sk. No: 9 D: 3 Beyo\u011flu\r\n* **Adres tarifi:** Taksim'den en kolay ula\u015f\u0131m yolu metro ile \u015ei\u015fhane istasyonunda indikten sonra, Me\u015frutiyet Caddesi \u00e7\u0131k\u0131\u015f\u0131n\u0131 kullanmak. Taksim y\u00f6n\u00fcnde y\u00fcr\u00fcrken sa\u011f taraftaki \u00fc\u00e7\u00fcnc\u00fc sokaktaki(Yemenici Abdullatif Sokak) 9 numaral\u0131 pembe bina.", "slug": "pyistanbul-8-subat-etkinligi", "is_published": true}}, {"pk": 4, "model": "blog.post", "fields": {"title": "Py\u0130stanbul 15 Mart Etkinli\u011fi", "created_at": "2014-03-05T17:56:40.631Z", "author": 2, "updated_at": "2014-03-13T08:37:17.129Z", "description": "**G\u00fcncelleme:** Etkinlik Nisan ay\u0131na ertelenmi\u015ftir.\r\n\r\nMart ay\u0131 etkinli\u011fimizi 15 Mart Cumartesi g\u00fcn\u00fc [Ubit](http://www.ubit.com.tr/)'in deste\u011fiyle Bah\u00e7e\u015fehir \u00dcniversitesi Be\u015fikta\u015f Yerle\u015fkesi'nde d\u00fczenliyoruz.\r\n\r\n### Etkinlik Program\u0131\r\n\r\n* **10:00/10:30** - Tan\u0131\u015fma, goygoy\r\n* **10:30/11:00** - Pratik Python, *Emre Y\u0131lmaz*\r\n* **11:10/12:10** - Elasticsearch, Logstash ve Kibana ile Logging, *G\u00fcrkan Olu\u00e7*\r\n* **12:10/13:00** - \u00d6\u011fle aras\u0131\r\n* **13:00/13:30** - Systemd ile s\u00fcre\u00e7 y\u00f6netimi, *Samed Beyribey*\r\n* **13:40/14:10** - GNU Emacs kullanarak Python ile geli\u015ftirme yapmak, *Muhammet Can*\r\n* **14:20/14:50** - Vim kullanarak Python ile geli\u015ftirme yapmak, *Zekeriya Ko\u00e7*\r\n\r\n\r\n![https://www.eventbrite.com/e/python-istanbul-15-mart-etkinligi-tickets-10839807155](https://www.eventbrite.com/custombutton?eid=10839807155)\r\n\r\n\r\n### Etkinlik Bilgileri\r\n\r\n* **Tarih:** 15 Mart 2014 Cumartesi\r\n* **Saat:** 10:00\r\n* **Adres:** Bah\u00e7e\u015fehir \u00dcniversitesi Be\u015fikta\u015f Yerle\u015fkesi, D salonu", "slug": "pyistanbul-15-mart-etkinligi", "is_published": true}}, {"pk": 5, "model": "blog.post", "fields": {"title": "Py\u0130stanbul 21 Haziran Etkinli\u011fi", "created_at": "2014-06-05T22:17:27.792Z", "author": 2, "updated_at": "2014-06-12T01:33:57.607Z", "description": "Haziran ay\u0131 etkinli\u011fimizi [\u0130T\u00dc \u00d6zg\u00fcr Yaz\u0131l\u0131m Kul\u00fcb\u00fc](http://ozguryazilim.itu.edu.tr/)'n\u00fcn deste\u011fiyle \u0130T\u00dc Ayaza\u011fa Yerle\u015fkesi'nde d\u00fczenliyoruz. Yerle\u015fkeye giri\u015fte problem ya\u015famamak i\u00e7in l\u00fctfen Eventbrite \u00fczerinden [kay\u0131t olun](https://www.eventbrite.com/e/python-istanbul-21-haziran-etkinligi-tickets-11877522991).\r\n\r\n![https://www.eventbrite.com/e/python-istanbul-21-haziran-etkinligi-tickets-11877522991](https://www.eventbrite.com/custombutton?eid=10839807155)\r\n\r\n### Etkinlik Program\u0131\r\n\r\n* **10:00/10:30** - Tan\u0131\u015fma, goygoy\r\n* **10:30/11:00** - Docker: Linux containerlar\u0131n gelece\u011fi, *Cihan Okyay*\r\n* **11:10/12:10** - Elasticsearch, Logstash ve Kibana ile logging, *G\u00fcrkan Olu\u00e7*\r\n* **12:10/13:00** - \u00d6\u011fle aras\u0131\r\n* **13:00/13:30** - Python ile genetik algoritmalar, *Neslihan \u015eirin Sayg\u0131l\u0131*\r\n* **13:40/14:10** - GNU Emacs kullanarak Python ile geli\u015ftirme yapmak, *Muhammet Can*\r\n* **14:20/14:50** - Vim kullanarak Python ile geli\u015ftirme yapmak, *Zekeriya Ko\u00e7*\r\n\r\n### Etkinlik Bilgileri\r\n\r\n* **Tarih:** 21 Haziran 2014 Cumartesi\r\n* **Saat:** 10:00\r\n* **Adres:** \u0130T\u00dc K\u00fclt\u00fcr ve Sanat Birli\u011fi Ana Bina (KSB) K\u00fc\u00e7\u00fck Salon, Ayaza\u011fa Yerle\u015fkesi Maslak/\u0130stanbul\r\n* **Adres tarifi:** KSB'ye Metro'dan ula\u015f\u0131m i\u00e7in, metro \u00e7\u0131k\u0131\u015f\u0131nda turnikelerin oldu\u011fu ana kap\u0131dan i\u00e7eri girdikten sonra a\u015fa\u011f\u0131ya do\u011fru d\u00fcmd\u00fcz devam ediyoruz. S\u00fcleyman Demirel K\u00fclt\u00fcr Merkezini ge\u00e7tikten sonraki binan\u0131n ilerisinden(merkezi dersliklerin arkas\u0131ndan) sola d\u00f6n\u00fcyoruz. Yolun sonundaki merdivenlerden yukar\u0131 \u00e7\u0131k\u0131nca soldaki kap\u0131dan i\u00e7eri giriyoruz.\r\n* **Google Maps:** https://goo.gl/maps/7ugHI\r\n* **Kroki:** https://dl.dropboxusercontent.com/u/166024/ksb-tarif.jpg", "slug": "pyistanbul-21-haziran-etkinligi", "is_published": true}}, {"pk": 6, "model": "blog.post", "fields": {"title": "Py\u0130stanbul 25 Ekim Etkinli\u011fi", "created_at": "2014-10-19T19:10:00.000Z", "author": 2, "updated_at": "2014-10-19T19:13:50.190Z", "description": "Ekim ay\u0131 etkinli\u011fimizi [\u0130T\u00dc \u00d6zg\u00fcr Yaz\u0131l\u0131m Kul\u00fcb\u00fc](http://ozguryazilim.itu.edu.tr/)'n\u00fcn deste\u011fiyle \u0130T\u00dc Ayaza\u011fa Yerle\u015fkesi'nde d\u00fczenliyoruz. Yerle\u015fkeye giri\u015fte problem ya\u015famamak i\u00e7in l\u00fctfen Eventbrite \u00fczerinden [kay\u0131t olun](https://www.eventbrite.com/e/python-istanbul-25-ekim-etkinligi-tickets-13804578867).\r\n\r\n![https://www.eventbrite.com/e/python-istanbul-25-ekim-etkinligi-tickets-13804578867](https://www.eventbrite.com/custombutton?eid=13804578867)\r\n\r\n### Etkinlik Program\u0131\r\n\r\n* **10:00/10:30** - Tan\u0131\u015fma, goygoy\r\n* **10:30/11:00** - Supervisor ile s\u00fcre\u00e7 y\u00f6netimi, *Aydan Ta\u015fdemir*\r\n* **11:20/12:00** - Ansible ile Django deployment, *Cihan Okyay*\r\n* **12:00/13:00** - \u00d6\u011fle aras\u0131\r\n* **13:00/13:40** - Flask ile REST API, *Eren T\u00fcrkay*\r\n* **14:00/14:30** - Networkx - Complex Networks, *Fatih Erikli*\r\n\r\n### Etkinlik Bilgileri\r\n\r\n* **Tarih:** 25 Ekim 2014 Cumartesi\r\n* **Saat:** 10:00\r\n* **Adres:** \u0130T\u00dc K\u00fclt\u00fcr ve Sanat Birli\u011fi Ana Bina (KSB) B\u00fcy\u00fck Salon, Ayaza\u011fa Yerle\u015fkesi Maslak/\u0130stanbul\r\n* **Adres tarifi:** KSB'ye Metro'dan ula\u015f\u0131m i\u00e7in, metro \u00e7\u0131k\u0131\u015f\u0131nda turnikelerin oldu\u011fu ana kap\u0131dan i\u00e7eri girdikten sonra a\u015fa\u011f\u0131ya do\u011fru d\u00fcmd\u00fcz devam ediyoruz. S\u00fcleyman Demirel K\u00fclt\u00fcr Merkezini ge\u00e7tikten sonraki binan\u0131n ilerisinden(merkezi dersliklerin arkas\u0131ndan) sola d\u00f6n\u00fcyoruz. Yolun sonundaki merdivenlerden yukar\u0131 \u00e7\u0131k\u0131nca soldaki kap\u0131dan i\u00e7eri giriyoruz.\r\n* **Google Maps:** https://goo.gl/maps/7ugHI\r\n* **Kroki:** https://dl.dropboxusercontent.com/u/166024/ksb-tarif.jpg\r\n* **Detayl\u0131 bilgi:** http://www.ksb.itu.edu.tr/ksb/iletisim-2", "slug": "pyistanbul-25-ekim-etkinligi", "is_published": true}}, {"pk": 7, "model": "blog.post", "fields": {"title": "Akademik Bili\u015fim 2015'teyiz", "created_at": "2015-01-02T22:11:54.016Z", "author": 1, "updated_at": "2015-01-02T22:25:08.004Z", "description": "Akademik Bili\u015fim konferans\u0131 bu sene Anadolu \u00dcniversitesi ev sahipli\u011fiyle Eski\u015fehir'de yap\u0131lacak. Her sene oldu\u011fu gibi bu sene de konferans \u00f6ncesi kurs ve e\u011fitimler ger\u00e7ekle\u015ftiriliyor. Bu sene Python hakk\u0131nda 5 kurs bulunmaktad\u0131r.\r\n\r\nPython hakk\u0131ndaki kurslar:\r\n\r\n- Python ile Web Geli\u015ftiricili\u011fi\r\n- Python ve Django ile Web Uygulamas\u0131 Geli\u015ftirme\r\n- Python ile RESTful Mikro Servisler Geli\u015ftirmek\r\n- Python ile Oyun Programlamaya Giri\u015f\r\n- Python ve R ile Bilimsel Hesaplama\r\n\r\nPython ile Web Geli\u015ftiricili\u011fi e\u011fitimi Python \u0130stanbul \u00fcyeleri taraf\u0131ndan verilmektedir.\r\n\r\nG\u00fcncel web geli\u015ftirme teknikleri ve API'lar hakk\u0131nda h\u0131zland\u0131r\u0131lm\u0131\u015f bir kurs. Yo\u011fun olarak belirli problemler i\u00e7in kullan\u0131lan tekniklerden ve teknolojlerden bahsedilecek. Bu problemler konum tabanl\u0131 bir servis geli\u015ftirmek, ya da karma\u015f\u0131k ili\u015fkilere sahip bir sosyal a\u011f yazmak gibi olabilir.\r\n\r\nKursun i\u00e7eri\u011fi a\u015fa\u011f\u0131daki gibi olacak.\r\n\r\nGiri\u015f\r\n-----\r\n\r\n- Web development i\u00e7in kullan\u0131lan diller\r\n- Neden bu kursun konusu Python?\r\n- Dil se\u00e7iminde toplulu\u011fun \u00f6nemi\r\n\r\nTemel Python (h\u0131zl\u0131ca \u00fczerinden ge\u00e7ilecek)\r\n------------------------------------------\r\n\r\n- Python'da \u00e7ok s\u0131k kullan\u0131lan veri yap\u0131lar\u0131\r\n- Fonksiyonlar ve birinci s\u0131n\u0131f objeler\r\n- S\u0131n\u0131flar ve Nesne y\u00f6nelimli programlama\r\n- Mod\u00fcl ve paket kavramlar\u0131\r\n- Standart k\u00fct\u00fcphanede en \u00e7ok kullan\u0131lan mod\u00fcller\r\n\r\nWeb Development\r\n---------------\r\n\r\n- Web Framework'ler (k\u0131saca bilgilendirme)\r\n- Full-stack framework'ler (Django, TurboGears)\r\n- Non-blocking framework'ler (Tornado)\r\n- Micro-framework'ler (Flask, Bottle)\r\n- MVC ve t\u00fcrevi mimariler\r\n- Model Kavram\u0131\r\n- View ve Controller Kavramlar\u0131\r\n- ORM nedir? Gerekli mi?\r\n\r\nVeritaban\u0131 Katman\u0131\r\n------------------\r\n\r\n- \u0130li\u015fkisel veritabanlar\u0131 (PostgreSQL)\r\n- NoSQL Veritabanlar\u0131\r\n- D\u00f6k\u00fcman tabanl\u0131 veritabanlar\u0131 (MongoDB)\r\n- Graph tabanl\u0131 veritabanlar\u0131 (Neo4J)\r\n- Key-value tabanl\u0131 veritabanlar\u0131 (Redis)\r\n- Uygun veritaban\u0131 mimarileri se\u00e7imi\r\n\r\nAPI Development\r\n---------------\r\n\r\n- API (Application Programming Interface) Nedir\r\n- REST Nedir? Bir standart m\u0131d\u0131r?\r\n- HTTP Metodlar\u0131; her \u015fey GET ve POST de\u011fil!\r\n- Python'da API Framework'leri\r\n- Lokasyon bazl\u0131 API'lar geli\u015ftirmek\r\n- API Development i\u00e7in hayat kolayla\u015ft\u0131r\u0131c\u0131 ara\u00e7lar\r\n- API'larda versiyonlama ve d\u00f6k\u00fcmantasyon\r\n\r\nG\u00fcvenlik\r\n--------\r\n\r\n- Web G\u00fcvenli\u011fine K\u0131saca Giri\u015f\r\n- SQL Injection ve XSS gibi temel kavramlar \r\n- CSRF nedir? \u00d6nlem i\u00e7in csrf_token yeterli mi?\r\n\r\nDeployment\r\n----------\r\n\r\n- Sunucu se\u00e7imi\r\n- Ngninx ile Load Balancing\r\n- Deployment ortam\u0131nda dikkat edilmesi gerekenler\r\n\r\n\r\n\r\n\r\n\r\nKurs hakk\u0131nda daha fazla bilgi ve kay\u0131t i\u00e7in a\u015fa\u011f\u0131daki ba\u011flant\u0131y\u0131 inceleyebilirsiniz.\r\n\r\n- http://ab.org.tr/ab15/Kurs/5.html\r\n- http://ab2015.anadolu.edu.tr\r\n", "slug": "akademik-bilisim-2015", "is_published": true}}] 2 | -------------------------------------------------------------------------------- /static_files/css/main.css: -------------------------------------------------------------------------------- 1 | /* base */ 2 | 3 | #pyistanbul .fixed-info { 4 | height: 510px; 5 | padding-top: 95px; 6 | background-color: #fff; 7 | } 8 | 9 | .collapsing { 10 | position: relative; 11 | height: 0; 12 | overflow: hidden; 13 | transition-timing-function: ease; 14 | transition-duration: .5s; 15 | transition-property: height; 16 | 17 | &.width { 18 | width: 0; 19 | height: auto; 20 | transition-property: width; 21 | } 22 | } 23 | 24 | .fixed-info .info { 25 | padding-top: 170px; 26 | background-size: 150px; 27 | background-position-x: center; 28 | background-repeat: no-repeat; 29 | text-align: center; 30 | } 31 | 32 | .fixed-info .what { 33 | background-image: url("../images/what-icon.png"); 34 | } 35 | 36 | .fixed-info .contact { 37 | background-image: url("../images/contact-icon.png"); 38 | } 39 | 40 | .fixed-info .support { 41 | background-image: url("../images/newsletter-icon.png"); 42 | } 43 | 44 | .fixed-info .info .sub-title { 45 | font-size: 18px; 46 | color: #4a4a4a; 47 | font-weight: 700; 48 | margin-bottom: 5px; 49 | font-family: 'Montserrat'; 50 | } 51 | 52 | .fixed-info .info p { 53 | width: 250px; 54 | color: #9b9b9b; 55 | font-size: 18px; 56 | margin: 0 auto; 57 | } 58 | 59 | .fixed-info .info p a { 60 | color: #4a90e2; 61 | } 62 | 63 | .card-body { 64 | padding: 30px 0; 65 | } 66 | 67 | /* header */ 68 | 69 | header { 70 | width: 100%; 71 | height: 90px; 72 | background-color: rgba(48, 40, 143, 0.9); 73 | position: relative; 74 | z-index: 3; 75 | } 76 | 77 | header._home { 78 | background: none; 79 | } 80 | 81 | header .navbar { 82 | padding: 0; 83 | line-height: 90px; 84 | } 85 | 86 | .nav-item { 87 | position: relative; 88 | height: 90px; 89 | margin-right: 40px; 90 | } 91 | 92 | .nav-item:last-child { 93 | margin-right: 0; 94 | } 95 | 96 | .nav-item.active:after { 97 | content: ""; 98 | position: absolute; 99 | bottom: -1px; 100 | left: 0; 101 | width: 100%; 102 | border-bottom: 8px solid rgba(255, 255, 255, 0.1); 103 | } 104 | 105 | .nav-item.active a { 106 | color: #ffd646; 107 | font-family: 'Montserrat'; 108 | } 109 | 110 | .nav-item a { 111 | color: #fff; 112 | } 113 | 114 | .nav-item a:hover { 115 | color: #ffd646; 116 | text-decoration: none; 117 | } 118 | 119 | .nav-item.logo { 120 | display: table-cell; 121 | } 122 | 123 | .nav-item.logo a { 124 | width: 132px; 125 | height: 153px; 126 | display: table-cell; 127 | vertical-align: middle; 128 | background-color: #fff; 129 | box-shadow: 0 3px 2px 0px rgba(0, 0, 0, 0.2); 130 | } 131 | 132 | /* footer */ 133 | 134 | footer { 135 | padding: 100px 0 30px; 136 | } 137 | 138 | footer form button { 139 | font-family: 'Roboto'; 140 | font-size: 18px; 141 | color: #fff; 142 | border-radius: 0; 143 | background-color: #3023ae; 144 | } 145 | 146 | footer .row .col-title { 147 | color: #9b9b9b; 148 | font-size: 16px; 149 | font-family: 'Montserrat'; 150 | margin-bottom: 30px; 151 | } 152 | 153 | footer .github { 154 | color: #9b9b9b; 155 | font-size: 24px; 156 | font-family: 'Roboto'; 157 | } 158 | 159 | footer .github:hover { 160 | text-decoration: none; 161 | } 162 | 163 | footer .github:before { 164 | content: "\f09b"; 165 | font-family: "FontAwesome"; 166 | } 167 | 168 | footer .copyright { 169 | margin-top: 110px; 170 | padding-top: 20px; 171 | border-top: 1px solid #e7e7e7; 172 | } 173 | 174 | footer .copyright span { 175 | position: relative; 176 | color: #9b9b9b; 177 | font-size: 13px; 178 | font-family: 'Roboto'; 179 | } 180 | 181 | footer .copyright span:before { 182 | content: ""; 183 | top: -6px; 184 | left: -40px; 185 | position: absolute; 186 | width: 31px; 187 | height: 30px; 188 | background: url("../images/footer-logo.png") no-repeat 0 0; 189 | } 190 | 191 | /* base page */ 192 | .page { 193 | padding-bottom: 60px; 194 | background-color: #e7e7e7; 195 | } 196 | 197 | .no-padding { 198 | padding: 0 !important; 199 | margin: 0 !important; 200 | } 201 | 202 | .top-shift { 203 | top: -20px; 204 | position: relative; 205 | } 206 | 207 | .cover { 208 | height: 160px; 209 | background-color: rgba(51, 51, 51, 0.8); 210 | } 211 | 212 | .cover h2 { 213 | color: #ffd646; 214 | font-size: 34px; 215 | line-height: 40px; 216 | margin-top: 70px; 217 | font-weight: 700; 218 | font-family: 'Montserrat'; 219 | } 220 | 221 | 222 | /* people page */ 223 | .people { 224 | margin-top: -20px; 225 | } 226 | 227 | .person { 228 | text-align: center; 229 | margin-bottom: 20px; 230 | } 231 | 232 | .person img { 233 | width: 220px; 234 | height: 220px; 235 | border-radius: 50%; 236 | } 237 | 238 | .person .p-name { 239 | font-size: 26px; 240 | color: #404040; 241 | margin-top: 15px; 242 | font-family: 'Roboto'; 243 | } 244 | 245 | .person .p-company { 246 | font-size: 16; 247 | line-height: 24px; 248 | color: #9b9b9b; 249 | margin-bottom: 5px; 250 | font-family: 'Roboto'; 251 | } 252 | 253 | .person .p-company span { 254 | display: block; 255 | } 256 | 257 | .person .p-social { 258 | padding: 0; 259 | display: inline-block; 260 | } 261 | 262 | .person .p-social li { 263 | float: left; 264 | margin-right: 13px; 265 | list-style-type: none; 266 | } 267 | 268 | .person .p-social a { 269 | color: #3486ff; 270 | font-size: 21px; 271 | text-decoration: none; 272 | } 273 | 274 | .person .p-social .a-twitter a:before { 275 | content: "\f099"; 276 | font-family: "FontAwesome"; 277 | } 278 | 279 | .person .p-social .a-github a:before { 280 | content: "\f099"; 281 | font-family: "FontAwesome"; 282 | } 283 | 284 | .person .p-social .a-twitter a:before { 285 | content: "\f09b"; 286 | font-family: "FontAwesome"; 287 | } 288 | 289 | .person .p-social .a-blog a:before { 290 | content: "\f015"; 291 | font-family: "FontAwesome"; 292 | } 293 | 294 | .people .new-person-btn { 295 | width: 220px; 296 | height: 220px; 297 | border-radius: 50%; 298 | cursor: pointer; 299 | background-color: #d8d8d8; 300 | margin: 0 auto; 301 | display: table; 302 | } 303 | 304 | .people .new-person-btn:before { 305 | color: #b9b9b9; 306 | content: "\f067"; 307 | font-size: 80px; 308 | font-family: "FontAwesome"; 309 | vertical-align: middle; 310 | display: table-cell; 311 | } 312 | 313 | #new-person-form { 314 | transition: none; 315 | background-color: rgba(48, 40, 143, 0.9); 316 | } 317 | 318 | #new-person-form .modal-dialog { 319 | width: 460px; 320 | } 321 | 322 | #new-person-form .modal-content { 323 | border-radius: 0; 324 | -webkit-border-radius: 0; 325 | -moz-border-radius: 0; 326 | } 327 | 328 | #new-person-form .modal-header .modal-title { 329 | color: #3023ae; 330 | width: 100%; 331 | text-align: center; 332 | font-size: 24px; 333 | font-weight: 700; 334 | font-family: 'Montserrat'; 335 | } 336 | 337 | #new-person-form .modal-header button { 338 | position: absolute; 339 | top: 20px; 340 | right: 20px; 341 | color: #9b9b9b; 342 | } 343 | 344 | #new-person-form .modal-body { 345 | padding: 20px 50px 40px; 346 | } 347 | 348 | #new-person-form form label { 349 | color: #474747; 350 | font-size: 14px; 351 | font-weight: 500; 352 | font-family: 'Roboto'; 353 | } 354 | 355 | #new-person-form form input { 356 | background-color: #f8f8f8; 357 | } 358 | 359 | #new-person-form form input.form-control:focus { 360 | border-color: #d0d0d0; 361 | box-shadow: 0 0 0 0.2rem rgba(0, 0, 0, 0.15); 362 | } 363 | 364 | #new-person-form form button { 365 | margin-top: 30px; 366 | box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.5); 367 | background-image: linear-gradient(to bottom, #5e49d7, #3023ae); 368 | } 369 | 370 | /* presentation page */ 371 | 372 | .event .event-title { 373 | width: 100%; 374 | padding: 0 20px; 375 | font-size: 18px; 376 | font-weight: 500; 377 | font-family: 'Roboto'; 378 | margin-bottom: 20px; 379 | } 380 | 381 | .event .speakers { 382 | width: 100%; 383 | height: 120px; 384 | line-height: 120px; 385 | text-align: center; 386 | margin: 0 0 20px 0; 387 | background-color: rgba(238, 238, 238, 0.9); 388 | } 389 | 390 | .event .speakers ul { 391 | padding: 0; 392 | margin: 0; 393 | display: inline-block; 394 | } 395 | 396 | .event .speakers li { 397 | float: left; 398 | margin-left: -20px; 399 | list-style-type: none; 400 | } 401 | 402 | .event .speakers li:first-child { 403 | margin-left: 0; 404 | } 405 | 406 | .event .speakers li img { 407 | border-radius: 50%; 408 | width: 86px; 409 | height: 86px; 410 | } 411 | 412 | .event .presentations { 413 | padding: 0 20px; 414 | } 415 | 416 | .event .presentations .presentation { 417 | margin-bottom: 10px; 418 | } 419 | 420 | .event .presentations .presentation-title { 421 | color: #3023ae; 422 | font-size: 16px; 423 | font-weight: 500; 424 | font-family: 'Roboto'; 425 | } 426 | 427 | .event .presentations .speaker-name { 428 | color: #404040; 429 | font-size: 14px; 430 | font-weight: 500; 431 | font-family: 'Roboto'; 432 | } 433 | 434 | /* home page */ 435 | .home { 436 | width: 100%; 437 | height: 700px; 438 | position: relative; 439 | z-index: 2; 440 | background: url("../images/home-bg.jpeg") no-repeat center center fixed; 441 | -webkit-background-size: cover; 442 | -moz-background-size: cover; 443 | -o-background-size: cover; 444 | background-size: cover; 445 | margin-top: -90px; 446 | padding-top: 140px; 447 | } 448 | 449 | .home:before { 450 | content: ""; 451 | height: 100%; 452 | width: 100%; 453 | position: absolute; 454 | top: 0; 455 | left: 0; 456 | z-index: 1; 457 | background-color: rgba(48, 40, 143, 0.9); 458 | } 459 | 460 | .home .no-event { 461 | width: 620px; 462 | position: relative; 463 | z-index: 2; 464 | margin: 120px auto 0; 465 | text-align: center; 466 | } 467 | 468 | .home .no-event .newsletter-title { 469 | color: #ffd646; 470 | font-size: 14px; 471 | font-weight: 700; 472 | position: relative; 473 | font-family: 'Montserrat'; 474 | } 475 | 476 | .home .no-event .newsletter-title:before { 477 | content: ""; 478 | width: 132px; 479 | height: 1px; 480 | position: absolute; 481 | top: 23px; 482 | left: 50%; 483 | margin-left: -66px; 484 | background-color: #ffd646; 485 | } 486 | 487 | .home .no-event .newsletter-title:after { 488 | content: "\f107"; 489 | position: absolute; 490 | top: 22px; 491 | left: 50%; 492 | width: 10px; 493 | margin-left: -5px; 494 | color: #ffd646; 495 | font-family: "FontAwesome"; 496 | } 497 | 498 | .home .no-event .newsletter-text { 499 | color: #fff; 500 | font-size: 18px; 501 | font-weight: 500; 502 | margin-top: 40px; 503 | font-family: 'Roboto'; 504 | } 505 | 506 | .home .no-event .newsletter-text span { 507 | display: block; 508 | font-size: 16px; 509 | opacity: 0.8; 510 | margin-top: 5px; 511 | } 512 | 513 | .home .no-event form { 514 | margin-top: 40px; 515 | } 516 | 517 | .home .no-event form input { 518 | width: 380px; 519 | height: 46px; 520 | margin-right: 20px; 521 | float: left; 522 | border: none; 523 | border-radius: 0; 524 | } 525 | 526 | .home .no-event form button { 527 | color: #fff; 528 | float: left; 529 | height: 46px; 530 | width: calc(100% - 400px); 531 | box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.5); 532 | border: none; 533 | cursor: pointer; 534 | background-image: linear-gradient(to bottom, #5e49d7, #3023ae); 535 | } 536 | 537 | .home .no-event .submit-info { 538 | color: #9afb38; 539 | font-size: 16px; 540 | text-align: left; 541 | margin-top: 10px; 542 | font-family: 'Roboto'; 543 | position: relative; 544 | } 545 | 546 | .home .no-event .submit-info:before { 547 | content: "\f00c"; 548 | color: #9afb38; 549 | font-size: 18px; 550 | margin-right: 10px; 551 | font-family: "FontAwesome"; 552 | } 553 | 554 | .featured-events { 555 | background-color: #e7e7e7; 556 | position: relative; 557 | z-index: 2; 558 | overflow: hidden; 559 | padding-bottom: 70px; 560 | } 561 | 562 | .featured-events:before { 563 | content: ""; 564 | width: 100%; 565 | height: 260px; 566 | position: absolute; 567 | top: 0; 568 | left: 0; 569 | z-index: -1; 570 | background-color: #333333; 571 | } 572 | 573 | .featured-events .event-years { 574 | margin-top: 50px; 575 | } 576 | 577 | .featured-events .event-years .sub-title { 578 | color: #646464; 579 | font-size: 13px; 580 | font-weight: 700; 581 | width: 62px; 582 | font-family: 'Montserrat'; 583 | float: left; 584 | margin-right: 25px; 585 | } 586 | 587 | .featured-events .event-years .years { 588 | padding: 0; 589 | display: inline-block; 590 | float: left; 591 | } 592 | 593 | .featured-events .event-years .years li { 594 | list-style-type: none; 595 | float: left; 596 | margin-right: 25px; 597 | line-height: 31px; 598 | position: relative; 599 | } 600 | 601 | .featured-events .event-years .years li a { 602 | color: #9b9b9b; 603 | font-size: 24px; 604 | font-weight: 300; 605 | font-family: 'Montserrat'; 606 | text-decoration: none; 607 | } 608 | 609 | .featured-events .event-years .years li.active a { 610 | color: #fff; 611 | font-size: 36px; 612 | font-weight: 300; 613 | font-family: 'Montserrat'; 614 | } 615 | 616 | .featured-events .event-years .years li.active:after { 617 | content: "\f107"; 618 | font-family: "FontAwesome"; 619 | position: absolute; 620 | bottom: -20px; 621 | color: #ffd646; 622 | left: 50%; 623 | width: 10px; 624 | margin-left: -5px; 625 | } 626 | 627 | .featured-events .event-box-title { 628 | color: #ffd646; 629 | font-size: 24px; 630 | font-weight: 700; 631 | margin: 30px 0; 632 | font-family: 'Montserrat'; 633 | } 634 | 635 | .featured-events .event-boxes .event-box { 636 | background-color: #fff; 637 | width: calc((100% - 20px) / 2); 638 | box-shadow: 0 2px 3px 0px rgba(195, 195, 195, 0.5); 639 | } 640 | 641 | .featured-events .event-boxes .event-box > .row { 642 | margin: 0; 643 | } 644 | 645 | .featured-events .event-boxes .event-box:first-child { 646 | margin-right: 20px; 647 | } 648 | 649 | .featured-events .event-boxes .event-box img { 650 | width: 100%; 651 | border: 1px solid #fff; 652 | } 653 | 654 | .featured-events .event-boxes .event-box .event-details { 655 | padding: 25px; 656 | } 657 | 658 | .featured-events .event-boxes .event-box .event-details .date{ 659 | color: #9b9b9b; 660 | font-size: 12px; 661 | font-family: 'Roboto'; 662 | } 663 | 664 | .featured-events .event-boxes .event-box .event-details .event-title{ 665 | color: #404040; 666 | font-size: 18px; 667 | margin-top: 10px; 668 | margin-bottom: 20px; 669 | font-family: 'Roboto'; 670 | } 671 | 672 | .featured-events .event-details .location, .featured-events .event-details .detail { 673 | display: inline-block; 674 | margin-right: 25px; 675 | } 676 | 677 | .featured-events .event-details .location a, .featured-events .event-details .detail a { 678 | color: #9b9b9b; 679 | font-size: 16px; 680 | text-decoration: none; 681 | font-family: 'Roboto'; 682 | } 683 | 684 | .featured-events .event-details .location a:before { 685 | content: "\f124"; 686 | margin-right: 4px; 687 | font-family: "FontAwesome"; 688 | } 689 | 690 | .featured-events .event-details .detail a:before { 691 | content: "\f036"; 692 | margin-right: 4px; 693 | font-family: "FontAwesome"; 694 | } 695 | -------------------------------------------------------------------------------- /static_files/css/font-awesome.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} 5 | -------------------------------------------------------------------------------- /static_files/js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v4.1.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2018 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e(t.bootstrap={},t.jQuery,t.Popper)}(this,function(t,e,h){"use strict";function i(t,e){for(var n=0;nthis._items.length-1||t<0))if(this._isSliding)P(this._element).one(Q.SLID,function(){return e.to(t)});else{if(n===t)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},t._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},t._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=t.left+t.right
',trigger:"hover focus",title:"",delay:0,html:!(Ie={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"}),selector:!(Se={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)"}),placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent"},we="out",Ne={HIDE:"hide"+Ee,HIDDEN:"hidden"+Ee,SHOW:(De="show")+Ee,SHOWN:"shown"+Ee,INSERTED:"inserted"+Ee,CLICK:"click"+Ee,FOCUSIN:"focusin"+Ee,FOCUSOUT:"focusout"+Ee,MOUSEENTER:"mouseenter"+Ee,MOUSELEAVE:"mouseleave"+Ee},Oe="fade",ke="show",Pe=".tooltip-inner",je=".arrow",He="hover",Le="focus",Re="click",xe="manual",We=function(){function i(t,e){if("undefined"==typeof h)throw new TypeError("Bootstrap tooltips require Popper.js (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var t=i.prototype;return t.enable=function(){this._isEnabled=!0},t.disable=function(){this._isEnabled=!1},t.toggleEnabled=function(){this._isEnabled=!this._isEnabled},t.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=pe(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),pe(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(pe(this.getTipElement()).hasClass(ke))return void this._leave(null,this);this._enter(null,this)}},t.dispose=function(){clearTimeout(this._timeout),pe.removeData(this.element,this.constructor.DATA_KEY),pe(this.element).off(this.constructor.EVENT_KEY),pe(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&pe(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},t.show=function(){var e=this;if("none"===pe(this.element).css("display"))throw new Error("Please use show on visible elements");var t=pe.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){pe(this.element).trigger(t);var n=pe.contains(this.element.ownerDocument.documentElement,this.element);if(t.isDefaultPrevented()||!n)return;var i=this.getTipElement(),r=Fn.getUID(this.constructor.NAME);i.setAttribute("id",r),this.element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&pe(i).addClass(Oe);var o="function"==typeof this.config.placement?this.config.placement.call(this,i,this.element):this.config.placement,s=this._getAttachment(o);this.addAttachmentClass(s);var a=!1===this.config.container?document.body:pe(document).find(this.config.container);pe(i).data(this.constructor.DATA_KEY,this),pe.contains(this.element.ownerDocument.documentElement,this.tip)||pe(i).appendTo(a),pe(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new h(this.element,i,{placement:s,modifiers:{offset:{offset:this.config.offset},flip:{behavior:this.config.fallbackPlacement},arrow:{element:je},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){e._handlePopperPlacementChange(t)}}),pe(i).addClass(ke),"ontouchstart"in document.documentElement&&pe(document.body).children().on("mouseover",null,pe.noop);var l=function(){e.config.animation&&e._fixTransition();var t=e._hoverState;e._hoverState=null,pe(e.element).trigger(e.constructor.Event.SHOWN),t===we&&e._leave(null,e)};if(pe(this.tip).hasClass(Oe)){var c=Fn.getTransitionDurationFromElement(this.tip);pe(this.tip).one(Fn.TRANSITION_END,l).emulateTransitionEnd(c)}else l()}},t.hide=function(t){var e=this,n=this.getTipElement(),i=pe.Event(this.constructor.Event.HIDE),r=function(){e._hoverState!==De&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),pe(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(pe(this.element).trigger(i),!i.isDefaultPrevented()){if(pe(n).removeClass(ke),"ontouchstart"in document.documentElement&&pe(document.body).children().off("mouseover",null,pe.noop),this._activeTrigger[Re]=!1,this._activeTrigger[Le]=!1,this._activeTrigger[He]=!1,pe(this.tip).hasClass(Oe)){var o=Fn.getTransitionDurationFromElement(n);pe(n).one(Fn.TRANSITION_END,r).emulateTransitionEnd(o)}else r();this._hoverState=""}},t.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},t.isWithContent=function(){return Boolean(this.getTitle())},t.addAttachmentClass=function(t){pe(this.getTipElement()).addClass(Te+"-"+t)},t.getTipElement=function(){return this.tip=this.tip||pe(this.config.template)[0],this.tip},t.setContent=function(){var t=this.getTipElement();this.setElementContent(pe(t.querySelectorAll(Pe)),this.getTitle()),pe(t).removeClass(Oe+" "+ke)},t.setElementContent=function(t,e){var n=this.config.html;"object"==typeof e&&(e.nodeType||e.jquery)?n?pe(e).parent().is(t)||t.empty().append(e):t.text(pe(e).text()):t[n?"html":"text"](e)},t.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},t._getAttachment=function(t){return Ie[t.toUpperCase()]},t._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(t){if("click"===t)pe(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(t){return i.toggle(t)});else if(t!==xe){var e=t===He?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=t===He?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;pe(i.element).on(e,i.config.selector,function(t){return i._enter(t)}).on(n,i.config.selector,function(t){return i._leave(t)})}pe(i.element).closest(".modal").on("hide.bs.modal",function(){return i.hide()})}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},t._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},t._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||pe(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),pe(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?Le:He]=!0),pe(e.getTipElement()).hasClass(ke)||e._hoverState===De?e._hoverState=De:(clearTimeout(e._timeout),e._hoverState=De,e.config.delay&&e.config.delay.show?e._timeout=setTimeout(function(){e._hoverState===De&&e.show()},e.config.delay.show):e.show())},t._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||pe(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),pe(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?Le:He]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=we,e.config.delay&&e.config.delay.hide?e._timeout=setTimeout(function(){e._hoverState===we&&e.hide()},e.config.delay.hide):e.hide())},t._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},t._getConfig=function(t){return"number"==typeof(t=l({},this.constructor.Default,pe(this.element).data(),"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),Fn.typeCheckConfig(ve,t,this.constructor.DefaultType),t},t._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},t._cleanTipClass=function(){var t=pe(this.getTipElement()),e=t.attr("class").match(be);null!==e&&e.length&&t.removeClass(e.join(""))},t._handlePopperPlacementChange=function(t){var e=t.instance;this.tip=e.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},t._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(pe(t).removeClass(Oe),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},i._jQueryInterface=function(n){return this.each(function(){var t=pe(this).data(ye),e="object"==typeof n&&n;if((t||!/dispose|hide/.test(n))&&(t||(t=new i(this,e),pe(this).data(ye,t)),"string"==typeof n)){if("undefined"==typeof t[n])throw new TypeError('No method named "'+n+'"');t[n]()}})},s(i,null,[{key:"VERSION",get:function(){return"4.1.3"}},{key:"Default",get:function(){return Ae}},{key:"NAME",get:function(){return ve}},{key:"DATA_KEY",get:function(){return ye}},{key:"Event",get:function(){return Ne}},{key:"EVENT_KEY",get:function(){return Ee}},{key:"DefaultType",get:function(){return Se}}]),i}(),pe.fn[ve]=We._jQueryInterface,pe.fn[ve].Constructor=We,pe.fn[ve].noConflict=function(){return pe.fn[ve]=Ce,We._jQueryInterface},We),Jn=(qe="popover",Ke="."+(Fe="bs.popover"),Me=(Ue=e).fn[qe],Qe="bs-popover",Be=new RegExp("(^|\\s)"+Qe+"\\S+","g"),Ve=l({},zn.Default,{placement:"right",trigger:"click",content:"",template:''}),Ye=l({},zn.DefaultType,{content:"(string|element|function)"}),ze="fade",Ze=".popover-header",Ge=".popover-body",$e={HIDE:"hide"+Ke,HIDDEN:"hidden"+Ke,SHOW:(Je="show")+Ke,SHOWN:"shown"+Ke,INSERTED:"inserted"+Ke,CLICK:"click"+Ke,FOCUSIN:"focusin"+Ke,FOCUSOUT:"focusout"+Ke,MOUSEENTER:"mouseenter"+Ke,MOUSELEAVE:"mouseleave"+Ke},Xe=function(t){var e,n;function i(){return t.apply(this,arguments)||this}n=t,(e=i).prototype=Object.create(n.prototype),(e.prototype.constructor=e).__proto__=n;var r=i.prototype;return r.isWithContent=function(){return this.getTitle()||this._getContent()},r.addAttachmentClass=function(t){Ue(this.getTipElement()).addClass(Qe+"-"+t)},r.getTipElement=function(){return this.tip=this.tip||Ue(this.config.template)[0],this.tip},r.setContent=function(){var t=Ue(this.getTipElement());this.setElementContent(t.find(Ze),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(Ge),e),t.removeClass(ze+" "+Je)},r._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},r._cleanTipClass=function(){var t=Ue(this.getTipElement()),e=t.attr("class").match(Be);null!==e&&0=this._offsets[r]&&("undefined"==typeof this._offsets[r+1]||t