├── .gitignore ├── LICENSE.md ├── README.md ├── djangopress ├── __init__.py ├── accounts │ ├── __init__.py │ ├── admin.py │ ├── forms.py │ ├── menus.py │ ├── middleware.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_auto_20140927_1229.py │ │ ├── 0003_auto_20140928_1817.py │ │ ├── 0004_auto_20140928_1827.py │ │ ├── 0005_auto_20140928_1906.py │ │ ├── 0006_auto_20140928_1912.py │ │ ├── 0007_auto_20141019_2034.py │ │ ├── 0008_usersocial.py │ │ ├── 0009_auto_20170710_0953.py │ │ └── __init__.py │ ├── models.py │ ├── profile.py │ ├── profiles.py │ ├── static │ │ └── js │ │ │ └── quick-login.js │ ├── templates │ │ └── accounts │ │ │ ├── edit-profile.html │ │ │ ├── emails │ │ │ └── confirm.txt │ │ │ ├── logged_out.html │ │ │ ├── login.html │ │ │ ├── login_form.html │ │ │ ├── messages │ │ │ ├── account_activated.html │ │ │ ├── already_activated.html │ │ │ ├── invalid_activation.html │ │ │ ├── registered-message.html │ │ │ ├── resent_activation.html │ │ │ └── you_are_banned.html │ │ │ ├── password_change_form.html │ │ │ ├── password_reset_complete.html │ │ │ ├── password_reset_confirm.html │ │ │ ├── password_reset_done.html │ │ │ ├── password_reset_email.html │ │ │ ├── password_reset_form.html │ │ │ ├── password_reset_subject.txt │ │ │ ├── profile.html │ │ │ ├── profile_password.html │ │ │ ├── quick_login.html │ │ │ ├── register.html │ │ │ ├── user-list.html │ │ │ └── view-profile.html │ ├── templatetags │ │ ├── __init__.py │ │ └── accounts.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── blog │ ├── __init__.py │ ├── admin.py │ ├── feeds.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_auto_20150212_2223.py │ │ ├── 0003_auto_20150216_1953.py │ │ ├── 0004_auto_20150426_1817.py │ │ ├── 0005_blog_comments_enabled.py │ │ ├── 0006_auto_20150813_1000.py │ │ ├── 0007_auto_20170710_0959.py │ │ └── __init__.py │ ├── models.py │ ├── search_indexes.py │ ├── settings.py │ ├── sitemaps.py │ ├── static │ │ └── css │ │ │ └── blog.css │ ├── templates │ │ ├── blog │ │ │ ├── base.html │ │ │ ├── category.html │ │ │ ├── date_archive.html │ │ │ ├── entry.html │ │ │ ├── index.html │ │ │ ├── list_archive.html │ │ │ ├── list_categories.html │ │ │ ├── list_latest.html │ │ │ ├── post.html │ │ │ └── show_latest.html │ │ └── search │ │ │ └── indexes │ │ │ └── blog │ │ │ └── entry_text.txt │ ├── templatetags │ │ ├── __init__.py │ │ └── blog_tags.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── contact │ ├── __init__.py │ ├── admin.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_auto_20170710_0953.py │ │ ├── 0003_maillog_created_date.py │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ └── contact │ │ │ └── index.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── core │ ├── __init__.py │ ├── _dynamic.py │ ├── format │ │ ├── __init__.py │ │ ├── bbcode.py │ │ ├── html.py │ │ ├── library.py │ │ ├── magic_html.py │ │ ├── models.py │ │ ├── nodes.py │ │ ├── parser.py │ │ ├── restructed_text.py │ │ ├── smilies.py │ │ └── stripped_html.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_auto_20140928_1807.py │ │ ├── 0003_auto_20140928_1906.py │ │ ├── 0004_auto_20170710_0953.py │ │ └── __init__.py │ ├── models.py │ ├── search.py │ ├── sitemap.py │ ├── static │ │ └── css │ │ │ ├── code_highlight.css │ │ │ └── search.css │ ├── templates │ │ └── core │ │ │ ├── field_form.html │ │ │ ├── form.html │ │ │ ├── pagination.html │ │ │ ├── pagination_query.html │ │ │ └── simple_pagination.html │ ├── templatetags │ │ ├── __init__.py │ │ ├── field_form.py │ │ ├── show_pagination.py │ │ └── smart_truncate_chars.py │ ├── tests.py │ ├── util.py │ └── views.py ├── donate │ ├── __init__.py │ ├── admin.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_auto_20140909_0456.py │ │ ├── 0003_auto_20141109_2155.py │ │ ├── 0004_auto_20170710_0959.py │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ └── donate │ │ │ ├── index.html │ │ │ ├── list.html │ │ │ ├── process.html │ │ │ └── thanks.html │ ├── templatetags │ │ ├── __init__.py │ │ └── donate_tags.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── dump.sh ├── files │ ├── __init__.py │ ├── admin.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_auto_20150805_0726.py │ │ ├── 0003_auto_20170710_0953.py │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── forum │ ├── __init__.py │ ├── admin.py │ ├── feeds.py │ ├── forms.py │ ├── management │ │ ├── __init__.py │ │ └── commands │ │ │ ├── __init__.py │ │ │ ├── forum_check_spam.py │ │ │ ├── forum_clear_spam.py │ │ │ ├── forum_fix_counts.py │ │ │ └── forum_fix_refs.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_auto_20140927_1231.py │ │ ├── 0003_auto_20140928_1817.py │ │ ├── 0004_auto_20140928_1827.py │ │ ├── 0005_auto_20140928_1852.py │ │ ├── 0006_auto_20140928_1906.py │ │ ├── 0007_auto_20140928_1940.py │ │ ├── 0008_auto_20141005_1948.py │ │ ├── 0009_forumgroup_post_redirect_delay.py │ │ ├── 0010_auto_20150426_1817.py │ │ ├── 0011_auto_20150426_1821.py │ │ ├── 0012_auto_20170710_0959.py │ │ ├── 0013_auto_20170810_0859.py │ │ └── __init__.py │ ├── models.py │ ├── profile.py │ ├── search.py │ ├── search_indexes.py │ ├── static │ │ └── css │ │ │ └── forum.css │ ├── templates │ │ ├── forum │ │ │ ├── base.html │ │ │ ├── email │ │ │ │ ├── forum_subscription_notification.txt │ │ │ │ └── subscription_notification.txt │ │ │ ├── forum.html │ │ │ ├── index.html │ │ │ ├── post │ │ │ │ ├── action.html │ │ │ │ ├── actions.html │ │ │ │ ├── crumbs.html │ │ │ │ ├── edit.html │ │ │ │ ├── edit_denied.html │ │ │ │ ├── latest.html │ │ │ │ ├── list_posts.html │ │ │ │ ├── posted.html │ │ │ │ └── report.html │ │ │ ├── profile.html │ │ │ ├── profile_subscriptions.html │ │ │ ├── search.html │ │ │ ├── subscriptions.html │ │ │ └── thread │ │ │ │ ├── access.html │ │ │ │ ├── actions.html │ │ │ │ ├── closed.html │ │ │ │ ├── crumbs.html │ │ │ │ ├── denied.html │ │ │ │ ├── index.html │ │ │ │ ├── list.html │ │ │ │ ├── new.html │ │ │ │ ├── new_denied.html │ │ │ │ ├── post.html │ │ │ │ ├── reply.html │ │ │ │ ├── subscribed.html │ │ │ │ └── unsubscribed.html │ │ └── search │ │ │ └── indexes │ │ │ └── forum │ │ │ └── post_text.txt │ ├── templatetags │ │ ├── __init__.py │ │ └── forum_tags.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── gallery │ ├── __init__.py │ ├── admin.py │ ├── image_urls.py │ ├── menus.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_auto_20150801_0911.py │ │ ├── 0003_gallerysection_listed.py │ │ ├── 0004_auto_20150803_0505.py │ │ ├── 0005_auto_20150805_0826.py │ │ ├── 0006_image_position.py │ │ ├── 0007_auto_20150829_0924.py │ │ ├── 0008_auto_20150921_0602.py │ │ ├── 0009_auto_20170710_0953.py │ │ └── __init__.py │ ├── models.py │ ├── sitemaps.py │ ├── templates │ │ └── gallery │ │ │ ├── admin_change_gallery.html │ │ │ ├── admin_gallery_as_html.html │ │ │ ├── admin_images_as_html.html │ │ │ ├── gallery.html │ │ │ ├── index.html │ │ │ ├── slider.html │ │ │ └── tag.html │ ├── templatetags │ │ ├── __init__.py │ │ └── gallery_tags.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── iptools │ ├── __init__.py │ ├── admin.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ └── iptools │ │ │ └── index.html │ ├── templatetags │ │ ├── __init__.py │ │ └── iptools_tags.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── menus │ ├── __init__.py │ ├── admin.py │ ├── menu.py │ ├── menus.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_auto_20170710_0953.py │ │ └── __init__.py │ ├── models.py │ ├── static │ │ └── js │ │ │ └── menu.action.js │ ├── templatetags │ │ ├── __init__.py │ │ └── display_menu.py │ ├── tests.py │ └── views.py ├── pages │ ├── __init__.py │ ├── admin.py │ ├── forms.py │ ├── middleware.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_page_head_tags.py │ │ ├── 0003_auto_20140907_0926.py │ │ ├── 0004_auto_20140912_0112.py │ │ ├── 0005_auto_20141001_1845.py │ │ ├── 0006_auto_20141005_1948.py │ │ ├── 0007_auto_20150426_1817.py │ │ ├── 0008_auto_20150730_0004.py │ │ ├── 0009_page_image.py │ │ ├── 0010_auto_20150803_0515.py │ │ ├── 0011_auto_20170710_0953.py │ │ ├── 0012_auto_20170710_0959.py │ │ ├── 0013_auto_20170714_0541.py │ │ ├── 0014_auto_20170724_1238.py │ │ └── __init__.py │ ├── models.py │ ├── render.py │ ├── search_indexes.py │ ├── sitemaps.py │ ├── static │ │ └── pages │ │ │ └── images │ │ │ ├── accept.png │ │ │ ├── error.png │ │ │ ├── exclamation.png │ │ │ └── information.png │ ├── templates │ │ ├── pages │ │ │ ├── base.html │ │ │ ├── editor │ │ │ │ ├── block-form.html │ │ │ │ ├── block.html │ │ │ │ ├── details-form.html │ │ │ │ ├── details.html │ │ │ │ └── page_block.html │ │ │ └── js │ │ │ │ └── edit-page.js │ │ └── search │ │ │ └── indexes │ │ │ └── pages │ │ │ └── page_text.txt │ ├── templatetags │ │ ├── __init__.py │ │ └── pages_tags.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── pun_modules.py ├── search_sites.py ├── settings.py ├── settings_tinymce.py ├── setup.sh ├── sitemap.py ├── theme │ ├── __init__.py │ ├── admin.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── static │ │ └── themes │ │ │ └── default │ │ │ ├── handheld.css │ │ │ ├── print.css │ │ │ └── style.css │ ├── templatetags │ │ ├── __init__.py │ │ └── theme.py │ ├── tests.py │ ├── theme.py │ └── views.py └── urls.py ├── manage.py └── www └── static ├── images └── icons │ ├── browser.png │ ├── calendar.png │ ├── color-wheel.png │ ├── messenger.png │ ├── minimize.png │ ├── pastel-svg.png │ ├── suite.png │ ├── toolbar-buttons.png │ └── xrl.png ├── js └── jquery-1.5.js └── themes └── default ├── handheld.css ├── images ├── bar-small.png ├── bar.png ├── bracket.png ├── date.png ├── empty.gif ├── feed-hover.png ├── feed.png ├── footer.png ├── hbar.png ├── header.png ├── icons.png ├── link-bar-hover.png ├── link-bar.png ├── logo-text.png ├── menu.png ├── search-input.png ├── search.png ├── side.png ├── sub-menu.png ├── top-level-menu.png └── top.png ├── print.css ├── style.css ├── style.footer.all.css ├── style.footer.css ├── style.front.css ├── style.general.all.css ├── style.general.css ├── style.general.handheld.css ├── style.menu.css ├── style.page-edit.css ├── style.sidebar.all.css ├── style.sidebar.css ├── style.table.css ├── style.toolbar.css └── style.top-menu.css /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | .project 3 | .pydevproject 4 | .idea -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Michael Buckley 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # django-Press 2 | 3 | django-Press is a set of django applications that is intended to cover all of the basic applications that are needed to build a web site. It goal is to be to web masters, what django is to web developers. 4 | 5 | Each application is supposed to be loosely coupled, so that they can be used on their own, but may also do extra things when they are together. 6 | 7 | Currently there are applications for: 8 | 9 | * CMS 10 | * Forum 11 | * Blog 12 | * Contact Page 13 | * Accounts 14 | 15 | We plan to add 16 | 17 | * Private Messaging 18 | * Themes 19 | * File Uploads 20 | * Polls 21 | * Wiki 22 | 23 | django-Press is never intended to have have the best any of these types of applications. But solid basic versions, that work together nicely. 24 | 25 | It should currently be considered alpha, but is being used on and developed for [Codefisher.org](https://codefisher.org/) 26 | 27 | -------------------------------------------------------------------------------- /djangopress/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/__init__.py -------------------------------------------------------------------------------- /djangopress/accounts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/accounts/__init__.py -------------------------------------------------------------------------------- /djangopress/accounts/menus.py: -------------------------------------------------------------------------------- 1 | from djangopress.menus.menu import register 2 | from django.template import Template, RequestContext 3 | from django.urls import reverse 4 | 5 | class LoginRender(object): 6 | def __init__(self): 7 | self._members = Template(""" 8 |
  • Members 9 |
  • 13 | """) 14 | 15 | def render_menu(self, context, tree, menu=None): 16 | raise #we don't know how to do this 17 | 18 | def render_item(self, context, item, sub_menu): 19 | if context.get("user").is_authenticated(): 20 | return self._members.render(RequestContext(context.get("request"), {"user": context.get("user")})) 21 | else: 22 | if context.get("request").path == reverse('logout'): 23 | return Template("""
  • Login
  • """).render(context) 24 | return Template("""
  • Login
  • """).render(context) 25 | 26 | register('member', LoginRender()) -------------------------------------------------------------------------------- /djangopress/accounts/migrations/0002_auto_20140927_1229.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('accounts', '0001_initial'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='userprofile', 16 | name='last_ip_used', 17 | field=models.GenericIPAddressField(null=True, blank=True), 18 | ), 19 | migrations.AlterField( 20 | model_name='userprofile', 21 | name='registration_ip', 22 | field=models.GenericIPAddressField(null=True, blank=True), 23 | ), 24 | ] 25 | -------------------------------------------------------------------------------- /djangopress/accounts/migrations/0003_auto_20140928_1817.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('core', '0002_auto_20140928_1807'), 11 | ('accounts', '0002_auto_20140927_1229'), 12 | ] 13 | 14 | operations = [ 15 | migrations.RemoveField( 16 | model_name='userprofile', 17 | name='properties', 18 | ), 19 | migrations.AddField( 20 | model_name='userprofile', 21 | name='property', 22 | field=models.ForeignKey(blank=True, to='core.Property', null=True, on_delete=models.CASCADE), 23 | preserve_default=True, 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /djangopress/accounts/migrations/0004_auto_20140928_1827.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('core', '0002_auto_20140928_1807'), 11 | ('accounts', '0003_auto_20140928_1817'), 12 | ] 13 | 14 | operations = [ 15 | migrations.RemoveField( 16 | model_name='userprofile', 17 | name='property', 18 | ), 19 | migrations.AddField( 20 | model_name='userprofile', 21 | name='properties', 22 | field=models.ManyToManyField(to='core.Property', null=True, blank=True), 23 | preserve_default=True, 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /djangopress/accounts/migrations/0005_auto_20140928_1906.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | from django.conf import settings 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ('core', '0003_auto_20140928_1906'), 13 | ('accounts', '0004_auto_20140928_1827'), 14 | ] 15 | 16 | operations = [ 17 | migrations.CreateModel( 18 | name='UserProperty', 19 | fields=[ 20 | ('property_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='core.Property', on_delete=models.CASCADE)), 21 | ('user_profile', models.ForeignKey(related_name=b'properties', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), 22 | ], 23 | options={ 24 | }, 25 | bases=('core.property',), 26 | ), 27 | migrations.RemoveField( 28 | model_name='userprofile', 29 | name='properties', 30 | ), 31 | ] 32 | -------------------------------------------------------------------------------- /djangopress/accounts/migrations/0006_auto_20140928_1912.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('accounts', '0005_auto_20140928_1906'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='userprofile', 16 | name='date_of_birth', 17 | field=models.DateTimeField(null=True, blank=True), 18 | preserve_default=True, 19 | ), 20 | migrations.AddField( 21 | model_name='userprofile', 22 | name='gender', 23 | field=models.CharField(default=None, max_length=1, null=True, blank=True, choices=[(b'', b'Private'), (b'M', b'Male'), (b'F', b'Female')]), 24 | preserve_default=True, 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /djangopress/accounts/migrations/0007_auto_20141019_2034.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | import djangopress.accounts.models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('accounts', '0006_auto_20140928_1912'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='userprofile', 17 | name='avatar', 18 | field=models.ImageField(null=True, upload_to=djangopress.accounts.models.avatar_path, blank=True), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /djangopress/accounts/migrations/0008_usersocial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | from django.conf import settings 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ('accounts', '0007_auto_20141019_2034'), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='UserSocial', 18 | fields=[ 19 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 20 | ('account', models.CharField(max_length=20, choices=[(b'twitter', b'Twitter'), (b'google_plus', b'Google Plus'), (b'facebook', b'Facebook'), (b'linkedin', b'Linked In'), (b'pinterest', b'Pinterest')])), 21 | ('value', models.CharField(max_length=100)), 22 | ('user_profile', models.ForeignKey(related_name=b'social', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), 23 | ], 24 | options={ 25 | }, 26 | bases=(models.Model,), 27 | ), 28 | ] 29 | -------------------------------------------------------------------------------- /djangopress/accounts/migrations/0009_auto_20170710_0953.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.3 on 2017-07-10 09:54 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('accounts', '0008_usersocial'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='userprofile', 17 | name='email_settings', 18 | field=models.CharField(choices=[('HI', 'Hide Email'), ('SW', 'Show Email'), ('HB', 'Use Web Form')], default='HI', max_length=2), 19 | ), 20 | migrations.AlterField( 21 | model_name='userprofile', 22 | name='gender', 23 | field=models.CharField(blank=True, choices=[('', 'Private'), ('M', 'Male'), ('F', 'Female')], default=None, max_length=1, null=True), 24 | ), 25 | migrations.AlterField( 26 | model_name='userprofile', 27 | name='language', 28 | field=models.CharField(blank=True, max_length=50, null=True), 29 | ), 30 | migrations.AlterField( 31 | model_name='userprofile', 32 | name='timezone', 33 | field=models.CharField(blank=True, max_length=50, null=True), 34 | ), 35 | migrations.AlterField( 36 | model_name='userprofile', 37 | name='title', 38 | field=models.CharField(default='New member', max_length=100), 39 | ), 40 | migrations.AlterField( 41 | model_name='usersocial', 42 | name='account', 43 | field=models.CharField(choices=[('twitter', 'Twitter'), ('google_plus', 'Google Plus'), ('facebook', 'Facebook'), ('linkedin', 'Linked In'), ('pinterest', 'Pinterest')], max_length=20), 44 | ), 45 | ] 46 | -------------------------------------------------------------------------------- /djangopress/accounts/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/accounts/migrations/__init__.py -------------------------------------------------------------------------------- /djangopress/accounts/profiles.py: -------------------------------------------------------------------------------- 1 | 2 | class Profile(object): 3 | label = None 4 | show_tab = True 5 | 6 | def __init__(self, user): 7 | self._user = user 8 | 9 | def info(self): 10 | pass 11 | 12 | def edit(self, request): 13 | pass 14 | 15 | def admin(self, request): 16 | pass 17 | 18 | class ProfileText(object): 19 | def __init__(self, text): 20 | self._text = text 21 | 22 | def is_text(self): 23 | return True 24 | 25 | def __str__(self): 26 | return self._text 27 | 28 | class ProfileRegister(object): 29 | 30 | def __init__(self): 31 | self._profile = {} 32 | self._position = {} 33 | 34 | def __call__(self, name, cls, position=0): 35 | self._profile[name] = cls 36 | self._position[name] = position 37 | 38 | def get_profiles(self): 39 | return self._profile 40 | 41 | def get_positions(self): 42 | return self._position 43 | 44 | register = ProfileRegister() 45 | 46 | def autodiscover(): 47 | "based on the admin site autodiscover see that for more info" 48 | import copy 49 | from django.conf import settings 50 | from importlib import import_module 51 | from django.utils.module_loading import module_has_submodule 52 | 53 | for app in settings.INSTALLED_APPS: 54 | mod = import_module(app) 55 | try: 56 | before_import_registry = copy.copy(register._profile) 57 | import_module('%s.profile' % app) 58 | except: 59 | register._profile = before_import_registry 60 | if module_has_submodule(mod, 'profile'): 61 | raise -------------------------------------------------------------------------------- /djangopress/accounts/static/js/quick-login.js: -------------------------------------------------------------------------------- 1 | function startQuickLogin() { 2 | $("#quick-login-link").click(function( event ) { 3 | event.preventDefault(); 4 | $("#quick-login-link").hide(); 5 | loadQuickLogin(); 6 | }); 7 | } 8 | 9 | function loadQuickLogin() { 10 | $.ajax({ 11 | url: '/accounts/quick_login/', 12 | type: "GET", 13 | dataType: "html", 14 | success: function(data){ 15 | var content = $("#quick-login-content"); 16 | content.empty(); 17 | content.html(data); 18 | content.show(); 19 | $("#id_username").focus(); 20 | content.click(function(event) { 21 | if(event.target.id == "quick-login-form") { 22 | content.empty(); 23 | $("#quick-login-link").show(); 24 | } 25 | }); 26 | }, 27 | error: function(jqXHR, textStatus, errorThrown){ 28 | $("#quick-login-link").show(); 29 | } 30 | }); 31 | } 32 | -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/edit-profile.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load field_form %} 3 | 4 | {% block content %} 5 |

    {% if user.profile.avatar %}{% endif %} 6 | {{ user.username }}

    7 |
    8 | {% for tab_name, profile in profiles %} 9 | {% if not forloop.first %} • {% endif %} 10 | {{ profile.label }} 11 | {% endfor %} 12 |
    13 |

    {{ profile_label }}

    14 |
    15 | {% for form in profile_data.forms %} 16 | {% if form.is_text %} 17 | {{ form|safe }} 18 | {% else %} 19 | {% field_form form %} 20 | {% endif %} 21 | {% endfor %} 22 |
    23 | Submit 24 | {% csrf_token %} 25 | 26 |
    27 |
    28 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/emails/confirm.txt: -------------------------------------------------------------------------------- 1 | Dear {{ user.username }}, 2 | 3 | Thanks for registering at {{ site.name }}. To complete your registration please visit the following link: 4 | {{ scheme }}://{{ site.domain }}{% url 'accounts-confirm' username=user.username activate_key=profile.activate_key %} 5 | 6 | If you did no register please ignore this email, and take no action. 7 | 8 | All the best, 9 | {{ site.name }} -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/logged_out.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |

    Loged Out

    5 |

    You have been loged out of your account.

    6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/login.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block content %} 3 | {% include "accounts/login_form.html" %} 4 | {% endblock %} 5 | -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/login_form.html: -------------------------------------------------------------------------------- 1 | {% load login_next from accounts %} 2 | 3 | {% if form.errors %} 4 |

    Your username and password didn't match. Please try again.

    5 | {% endif %} 6 |
    7 |
    8 | User Login 9 | {% csrf_token %} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
    {{ form.username.label_tag }}{{ form.username }}
    {{ form.password.label_tag }}{{ form.password }}
    20 |

    21 |

    22 | 23 |
    24 |
    25 |

    26 | If you don't have an account, please Register first. If you can not remember your password you can reset it. 27 |

    -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/messages/account_activated.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load login_form from accounts %} 3 | 4 | {% block content %} 5 |

    Account Validated

    6 |

    7 | {{ user.username|capfirst }}, your account has been validated, you can now login and return to what you were doing. 8 |

    9 | {% login_form '/' %} 10 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/messages/already_activated.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |

    Account Already Validated

    5 |

    6 | {{ user.username|capfirst }}, your account is already validated, there is no need to validate it again. 7 |

    8 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/messages/invalid_activation.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |

    Account could not be validated

    5 |

    6 | {{ user.username|capfirst }} your account could not be validated, either the validation link was incorrect or the validation period has expired. 7 |

    8 |
    9 | {% csrf_token %} 10 | 11 |
    12 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/messages/registered-message.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |

    Account Created

    5 |

    6 | {{ user.username|capfirst }}, your account has been created, and an activation email sent to your email address. Please check your email and follow the instructions given. 7 |

    8 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/messages/resent_activation.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |

    Resent Activation

    5 |

    6 | {{ user.username|capfirst }}, an activation email has been sent to your email address. Please check your email and follow the instructions given. 7 |

    8 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/messages/you_are_banned.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |

    Banned

    5 |

    6 | {{ user.username|capfirst }}, sorry but you have been banned and can not do this action. 7 |

    8 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/password_change_form.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 |

    Password change

    6 | 7 |

    8 | Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly. 9 |

    10 |
    11 |
    12 | {% csrf_token %} 13 | {{ form.as_p }} 14 | 15 |
    16 |
    17 | 18 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/password_reset_complete.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 |

    {{ title }}

    6 | 7 |

    Your password has been set. You may go ahead and log in now.

    8 | 9 |

    Log in

    10 | 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/password_reset_confirm.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 | {% if validlink %} 6 | 7 |

    Please enter your new password twice so we can verify you typed it in correctly.

    8 | 9 |
    10 |
    11 | {% csrf_token %} 12 | {{ form.as_p }} 13 |

    14 |
    15 |
    16 | 17 | {% else %} 18 | 19 |

    The password reset link was invalid, possibly because it has already been used. Please request a new password reset.

    20 | 21 | {% endif %} 22 | 23 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/password_reset_done.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 |

    Password reset successful

    6 | 7 |

    We've emailed you instructions for setting your password. You should be receiving them shortly.

    8 | 9 |

    If you don't receive an email, please make sure you've entered the address you registered with, and check your spam folder.

    10 | 11 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/password_reset_email.html: -------------------------------------------------------------------------------- 1 | {% load i18n %}{% autoescape off %} 2 | {% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %} 3 | 4 | {% trans "Please go to the following page and choose a new password:" %} 5 | {% block reset_link %} 6 | {{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %} 7 | {% endblock %} 8 | {% trans "Your username, in case you've forgotten:" %} {{ user.get_username }} 9 | 10 | {% trans "Thanks for using our site!" %} 11 | 12 | {% blocktrans %}The {{ site_name }} team{% endblocktrans %} 13 | 14 | {% endautoescape %} 15 | -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/password_reset_form.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 |

    Reset Password

    6 | 7 |

    8 | Forgotten your password? Enter your email address below, and we'll email instructions for setting a new one. 9 |

    10 |
    11 |
    12 | {% csrf_token %} 13 | {{ form.as_p }} 14 |

    15 |
    16 |
    17 | 18 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/password_reset_subject.txt: -------------------------------------------------------------------------------- 1 | {% load i18n %}{% autoescape off %} 2 | {% blocktrans %}Password reset on {{ site_name }}{% endblocktrans %} 3 | {% endautoescape %} -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/profile.html: -------------------------------------------------------------------------------- 1 | {% load online_status_tags %} 2 | {% load accounts %} 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
    Username{{ user.username }}
    Date Joined{{ user.date_joined }}
    Last Login{{ user.last_login }}
    Real Name{{ user.first_name }} {{ user.last_name }}
    Website{% if user.profile.homepage %}{{ user.profile.homepage }}{% endif %}
    Status{% user_status user %}
    24 | {% if user.profile.signature %} 25 |

    Signature

    26 |
    27 | {% show_signature user %} 28 |
    29 | {% endif %} 30 | -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/profile_password.html: -------------------------------------------------------------------------------- 1 |
    2 | Password 3 |

    Change your Password

    4 |
    -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/quick_login.html: -------------------------------------------------------------------------------- 1 | {% load login_next from accounts %} 2 | 3 |
    4 | {% csrf_token %} 5 |
    6 | 7 |
    8 |
    {{ form.username.label_tag }}{{ form.username }}
    9 |
    {{ form.password.label_tag }}{{ form.password }}
    10 |
    11 |
    12 |
    13 |
    Sign Up
    14 |
    15 |
    16 | 17 |
    18 |
    19 |
    20 |
    -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/register.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load field_form %} 3 | 4 | {% block content %} 5 |
    6 | {% field_form form %} 7 |
    8 | Submit 9 | {% csrf_token %} 10 | 11 |
    12 |
    13 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/user-list.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load show_pagination %} 3 | 4 | {% block content %} 5 |

    User List

    6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {% for user in users %} 16 | 17 | 18 | 19 | 20 | 21 | {% endfor %} 22 | 23 |
    User nameTitleRegistered
    {{ user.username }}{{ user.profile.title }}{{ user.date_joined|date:"DATE_FORMAT" }}
    24 | {% show_pagination users user_list_page %} 25 | {% endblock %}} -------------------------------------------------------------------------------- /djangopress/accounts/templates/accounts/view-profile.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |

    {% if user.profile.avatar %}{% endif %} 5 | {{ user.username }}

    6 | {% for profile in profile_data %} 7 |

    {{ profile.title }}

    8 | {% include profile.template %} 9 | {% endfor %} 10 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/accounts/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/accounts/templatetags/__init__.py -------------------------------------------------------------------------------- /djangopress/accounts/templatetags/accounts.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | from django.urls import reverse 3 | try: 4 | from urlparse import urlparse, urlunparse 5 | except ImportError: 6 | from urllib.parse import urlparse, urlunparse 7 | from django.contrib.auth.forms import AuthenticationForm 8 | from django.conf import settings 9 | from djangopress.core.format.library import Library 10 | 11 | register = template.Library() 12 | 13 | def remove_netloc(url): 14 | parsed = urlparse(url) 15 | return urlunparse(('', '') + parsed[2:]) 16 | 17 | @register.simple_tag(takes_context=True) 18 | def login_next(context, next_url): 19 | if not next_url or next_url == reverse('logout'): 20 | next_url = remove_netloc(context.get('request').META.get('HTTP_REFERER', '')) 21 | if next_url == reverse('logout'): 22 | next_url = "/" 23 | return next_url 24 | 25 | @register.inclusion_tag('accounts/login_form.html', takes_context=True) 26 | def login_form(context, next_url=None): 27 | return { 28 | "next": next_url if next_url else context['request'].path, 29 | "form": AuthenticationForm(context['request']), 30 | } 31 | 32 | @register.simple_tag(takes_context=True) 33 | def show_signature(context, user): 34 | if not user.profile.signature: 35 | return "" 36 | try: 37 | use_images = settings.ACCOUNTS_USER_LIMITS.get('signature', {}).get('images', True) 38 | use_links = settings.ACCOUNTS_USER_LIMITS.get('signature', {}).get('links', True) 39 | bbcode = Library.get("bbcode").get("function") 40 | return bbcode(user.profile.signature, context=context, show_images=use_images, should_urlize=use_links, render_links=use_links) 41 | except: 42 | return "" -------------------------------------------------------------------------------- /djangopress/accounts/tests.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file demonstrates two different styles of tests (one doctest and one 3 | unittest). These will both pass when you run "manage.py test". 4 | 5 | Replace these with more appropriate tests for your application. 6 | """ 7 | 8 | from django.test import TestCase 9 | 10 | class SimpleTest(TestCase): 11 | def test_basic_addition(self): 12 | """ 13 | Tests that 1 + 1 always equals 2. 14 | """ 15 | self.failUnlessEqual(1 + 1, 2) 16 | 17 | __test__ = {"doctest": """ 18 | Another way to test that 1 + 1 is equal to 2. 19 | 20 | >>> 1 + 1 == 2 21 | True 22 | """} 23 | 24 | -------------------------------------------------------------------------------- /djangopress/blog/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | from djangopress.core import dynamic 3 | from djangopress.blog import urls 4 | from djangopress.blog.models import Blog 5 | 6 | def test_slug(slug): 7 | return Blog.objects.get(slug=slug) 8 | 9 | dynamic.register("blog", test_slug, urls) 10 | """ -------------------------------------------------------------------------------- /djangopress/blog/feeds.py: -------------------------------------------------------------------------------- 1 | from djangopress.blog.models import Blog, Entry 2 | from django.shortcuts import get_object_or_404 3 | from django.contrib.syndication.views import Feed 4 | from django.urls import reverse 5 | from django.utils.feedgenerator import Atom1Feed 6 | 7 | class BlogFeed(Feed): 8 | 9 | def get_object(self, request, blog_slug=None): 10 | return get_object_or_404(Blog, slug=blog_slug) 11 | 12 | def title(self, obj): 13 | return obj.name 14 | 15 | def link(self, obj): 16 | kwargs = {} 17 | if obj.slug: 18 | kwargs["blog_slug"] = obj.slug 19 | return reverse("blog-index", kwargs=kwargs) 20 | 21 | def description(self, obj): 22 | return obj.tagline 23 | 24 | def items(self, obj): 25 | return Entry.objects.get_entries(blog=obj)[:10] 26 | 27 | def item_title(self, item): 28 | return item.title 29 | 30 | def item_description(self, item): 31 | return item.body 32 | 33 | def item_author_name(self, item): 34 | return item.author 35 | 36 | def item_pubdate(self, item): 37 | return item.posted 38 | 39 | def item_updateddate(self, item): 40 | return item.edited 41 | 42 | def item_categories(self, item): 43 | return (str(category) for category in item.categories.all()) 44 | 45 | class BlogAtomFeed(BlogFeed): 46 | feed_type = Atom1Feed 47 | 48 | def subtitle(self, obj): 49 | return self.description(obj) -------------------------------------------------------------------------------- /djangopress/blog/migrations/0002_auto_20150212_2223.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | import djangopress.blog.models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('blog', '0001_initial'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='entry', 17 | name='description', 18 | field=models.TextField(default=b'', blank=True), 19 | preserve_default=True, 20 | ), 21 | migrations.AddField( 22 | model_name='entry', 23 | name='post_image', 24 | field=models.ImageField(null=True, upload_to=djangopress.blog.models.post_image_path, blank=True), 25 | preserve_default=True, 26 | ), 27 | ] 28 | -------------------------------------------------------------------------------- /djangopress/blog/migrations/0003_auto_20150216_1953.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('blog', '0002_auto_20150212_2223'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='entry', 16 | name='description', 17 | field=models.TextField(default=b'', max_length=140, blank=True), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /djangopress/blog/migrations/0004_auto_20150426_1817.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('blog', '0003_auto_20150216_1953'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='comment', 16 | name='user_email', 17 | field=models.EmailField(max_length=254, verbose_name=b'Email address', blank=True), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /djangopress/blog/migrations/0005_blog_comments_enabled.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('blog', '0004_auto_20150426_1817'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='blog', 16 | name='comments_enabled', 17 | field=models.BooleanField(default=True), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /djangopress/blog/migrations/0006_auto_20150813_1000.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('blog', '0005_blog_comments_enabled'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='category', 16 | name='name', 17 | field=models.CharField(unique=True, max_length=30), 18 | ), 19 | migrations.AlterField( 20 | model_name='entry', 21 | name='categories', 22 | field=models.ManyToManyField(to='blog.Category', blank=True), 23 | ), 24 | migrations.AlterField( 25 | model_name='tag', 26 | name='name', 27 | field=models.CharField(unique=True, max_length=30), 28 | ), 29 | ] 30 | -------------------------------------------------------------------------------- /djangopress/blog/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/blog/migrations/__init__.py -------------------------------------------------------------------------------- /djangopress/blog/search_indexes.py: -------------------------------------------------------------------------------- 1 | from haystack import indexes 2 | from djangopress.blog.models import Entry 3 | 4 | class EntryIndex(indexes.SearchIndex, indexes.Indexable): 5 | text = indexes.CharField(document=True, use_template=True) 6 | author = indexes.CharField(model_attr='author') 7 | pub_date = indexes.DateTimeField(model_attr='posted') 8 | title = indexes.CharField(model_attr='title', boost=1.5) 9 | 10 | def get_model(self): 11 | return Entry 12 | 13 | def index_queryset(self, using=None): 14 | """Used when the entire index for model is updated.""" 15 | return self.get_model().objects.get_entries(ordered=False) 16 | 17 | def prepare(self, obj): 18 | data = super(EntryIndex, self).prepare(obj) 19 | data['boost'] = 1 20 | return data 21 | -------------------------------------------------------------------------------- /djangopress/blog/settings.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/blog/settings.py -------------------------------------------------------------------------------- /djangopress/blog/sitemaps.py: -------------------------------------------------------------------------------- 1 | from django.contrib.sitemaps import Sitemap 2 | from .models import Entry, Blog, Category, Tag 3 | from djangopress.core.sitemap import register 4 | from django.conf import settings 5 | 6 | #todo, add last mod field for Category and Tag 7 | 8 | class EntrySitemap(Sitemap): 9 | 10 | def items(self): 11 | return Entry.objects.get_entries(ordered=False).filter(blog__sites__id__exact=settings.SITE_ID) 12 | 13 | def lastmod(self, obj): 14 | return obj.edited 15 | 16 | register('blog-entry', EntrySitemap) 17 | 18 | class BlogSitemap(Sitemap): 19 | lastmod = None 20 | 21 | def items(self): 22 | return Blog.objects.filter(sites__id__exact=settings.SITE_ID) 23 | 24 | def lastmod(self, obj): 25 | try: 26 | return Entry.objects.get_entries(blog=obj)[0].edited 27 | except: 28 | return None 29 | 30 | register('blog', BlogSitemap) 31 | 32 | class CategorySitemap(Sitemap): 33 | lastmod = None 34 | 35 | def items(self): 36 | return Category.objects.filter(blog__sites__id__exact=settings.SITE_ID) 37 | 38 | register('blog-category', CategorySitemap) 39 | 40 | class TagSitemap(Sitemap): 41 | lastmod = None 42 | 43 | def items(self): 44 | return Tag.objects.filter(blog__sites__id__exact=settings.SITE_ID) 45 | 46 | register('blog-tag', TagSitemap) -------------------------------------------------------------------------------- /djangopress/blog/static/css/blog.css: -------------------------------------------------------------------------------- 1 | .previous-next-links .previous-link { 2 | float:left; 3 | } 4 | 5 | .previous-next-links .next-link { 6 | float:right; 7 | } 8 | 9 | .previous-next-links { 10 | padding:0 0 1em; 11 | font-size:0.75em; 12 | } 13 | .previous-next-links a { 14 | text-decoration:none; 15 | } 16 | .blog-entry h3 { 17 | padding:0; 18 | margin:1em 0 0; 19 | font-size:1.125em; 20 | clear:both; 21 | } 22 | 23 | .blog-entry small { 24 | font-size:0.675em; 25 | color:#000000; 26 | } 27 | 28 | .blog-entry h3 a { 29 | text-decoration:none; 30 | } 31 | 32 | .blog-entry-footer { 33 | padding:0.5em; 34 | text-align:center; 35 | } 36 | 37 | .blog-entry-tags, 38 | .blog-entry-links { 39 | display:block; 40 | font-size:0.8em; 41 | } 42 | 43 | h2.category { 44 | font-size:1.25em; 45 | text-align:center; 46 | } 47 | 48 | .comment { 49 | background:rgba(0, 0, 0, 0.2); 50 | border-radius:6px; 51 | box-shadow: 0px 0px 1px rgba(255, 255, 255, 0.5); 52 | border: 1px solid rgba(0, 0, 0, 0.6); 53 | padding:0.5em; 54 | margin:0.5em; 55 | } 56 | 57 | .comment-text { 58 | padding:0.5em; 59 | } 60 | 61 | .comment-info { 62 | border: 1px solid rgba(0, 0, 0, 0.6); 63 | background:rgba(0, 0, 0, 0.2); 64 | font-size:0.8em; 65 | padding:0.2em; 66 | } 67 | 68 | .author-comment { 69 | font-size:1.25em; 70 | text-shadow: #000000 1px 1px 1px; 71 | margin-left:1.5em; 72 | } 73 | -------------------------------------------------------------------------------- /djangopress/blog/templates/blog/base.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load static %} 3 | {% load blog_tags %} 4 | 5 | {% block page_title_prefix %}{% if title != blog.name %} :: {{ blog.name }}{% endif %}{% endblock %} 6 | 7 | {% block head_tags %} 8 | 9 | 10 | {% endblock %} 11 | 12 | {% block sidebar %} 13 | 21 | 29 | {{ block.super }} 30 | {% endblock %} 31 | 32 | {% block footer %} 33 | {{ block.super }} 34 | 37 | {% endblock %} 38 | -------------------------------------------------------------------------------- /djangopress/blog/templates/blog/category.html: -------------------------------------------------------------------------------- 1 | {% extends "blog/base.html" %} 2 | {% load show_pagination %} 3 | 4 | {% block content %} 5 | {% if blog_heading %} 6 |

    {{ blog_heading }}

    7 | {% endif %} 8 | {% for entry in entries.object_list %} 9 | {% include "blog/entry.html" %} 10 | {% endfor %} 11 | 12 | {% query_pagination entries %} 13 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/blog/templates/blog/date_archive.html: -------------------------------------------------------------------------------- 1 | {% extends "blog/base.html" %} 2 | {% load show_pagination %} 3 | 4 | {% block page_title %} 5 | {{ title }} :: Archive for {{ date|date:format }} 6 | {% endblock %} 7 | 8 | {% block content %} 9 |

    Archive for {{ date|date:format }}

    10 | {% for entry in entries.object_list %} 11 | {% include "blog/entry.html" %} 12 | {% endfor %} 13 | 14 | {% query_pagination entries %} 15 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/blog/templates/blog/index.html: -------------------------------------------------------------------------------- 1 | {% extends "blog/base.html" %} 2 | {% load show_pagination %} 3 | 4 | {% block content %} 5 | {% if blog_heading %} 6 |

    {{ blog_heading }}

    7 | {% endif %} 8 | {% for entry in entries.object_list %} 9 | {% include "blog/entry.html" %} 10 | {% endfor %} 11 | 12 | {% show_pagination entries blog %} 13 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/blog/templates/blog/list_archive.html: -------------------------------------------------------------------------------- 1 | {% for month in dates %} 2 |
  • {{ month|date:"YEAR_MONTH_FORMAT" }}
  • 3 | {% endfor %} -------------------------------------------------------------------------------- /djangopress/blog/templates/blog/list_categories.html: -------------------------------------------------------------------------------- 1 | {% for category in categories %} 2 |
  • {{ category.name }}
  • 3 | {% endfor %} -------------------------------------------------------------------------------- /djangopress/blog/templates/blog/list_latest.html: -------------------------------------------------------------------------------- 1 | {% for entry in entries %}
  • {{ entry.title }}
  • {% endfor %} -------------------------------------------------------------------------------- /djangopress/blog/templates/blog/show_latest.html: -------------------------------------------------------------------------------- 1 | {% for entry in entries %} 2 |
    3 | {% if images and entry.post_image %} 4 | 5 | {% endif %} 6 |

    {{ entry.title }}

    7 | {{ entry.posted|date:"M" }} {{ entry.posted|date:"jS" }} 8 | {{ entry.body|striptags|truncatewords:words }} Read More 9 |
    10 | {% endfor %} -------------------------------------------------------------------------------- /djangopress/blog/templates/search/indexes/blog/entry_text.txt: -------------------------------------------------------------------------------- 1 | {{ object.title }} 2 | {{ object.user.get_full_name }} 3 | {{ object.body|striptags|safe }} 4 | 5 | {% for tag in object.tags.all %} tag.name {% endfor %} 6 | {% for category in entry.categories.all %} category.name {% endfor %} -------------------------------------------------------------------------------- /djangopress/blog/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/blog/templatetags/__init__.py -------------------------------------------------------------------------------- /djangopress/blog/templatetags/blog_tags.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | from djangopress.blog.models import Entry, Blog, Category 3 | from django.utils import timezone 4 | 5 | register = template.Library() 6 | 7 | @register.inclusion_tag('blog/show_latest.html') 8 | def show_blog_latest(number=5, words=20, blog=None): 9 | blog = Blog.objects.get(slug=blog) 10 | try: 11 | number = int(number) 12 | except ValueError: 13 | number = 5 14 | entries_list = Entry.objects.get_entries(blog=blog)[0:number] 15 | return { 16 | "entries": entries_list, 17 | "words": words 18 | } 19 | 20 | @register.inclusion_tag('blog/list_latest.html') 21 | def list_blog_latest(number=5, blog=None): 22 | try: 23 | blog = Blog.objects.get(slug=blog) 24 | except Blog.DoesNotExist: 25 | return {} 26 | try: 27 | number = int(number) 28 | except ValueError: 29 | number = 5 30 | entries_list = Entry.objects.get_entries(blog=blog)[0:number] 31 | return { 32 | "entries": entries_list, 33 | "blog": blog, 34 | } 35 | 36 | @register.inclusion_tag('blog/list_archive.html') 37 | def list_blog_archive(blog): 38 | with timezone.override(None): 39 | entries_list = Entry.objects.get_entries(blog=blog) 40 | dates = entries_list.datetimes('posted', 'month', order='DESC') 41 | return { 42 | "dates": dates, 43 | } 44 | 45 | @register.inclusion_tag('blog/list_categories.html') 46 | def list_blog_categories(blog): 47 | return { 48 | "categories": Category.objects.get_categories(blog=blog), 49 | } -------------------------------------------------------------------------------- /djangopress/blog/tests.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file demonstrates two different styles of tests (one doctest and one 3 | unittest). These will both pass when you run "manage.py test". 4 | 5 | Replace these with more appropriate tests for your application. 6 | """ 7 | 8 | from django.test import TestCase 9 | 10 | class SimpleTest(TestCase): 11 | def test_basic_addition(self): 12 | """ 13 | Tests that 1 + 1 always equals 2. 14 | """ 15 | self.failUnlessEqual(1 + 1, 2) 16 | 17 | __test__ = {"doctest": """ 18 | Another way to test that 1 + 1 is equal to 2. 19 | 20 | >>> 1 + 1 == 2 21 | True 22 | """} 23 | 24 | -------------------------------------------------------------------------------- /djangopress/blog/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | from djangopress.blog.feeds import BlogFeed, BlogAtomFeed 3 | from djangopress.blog import views 4 | 5 | urlpatterns = [ 6 | url(r'^$', views.index, name='blog-index'), 7 | url(r'^page/(?P\d*)/$', views.index, name='blog-index'), 8 | 9 | url(r'^(?P\d{4})/$', views.archive, name='blog-archive'), 10 | url(r'^(?P\d{4})/(?P\d{1,2})/$', views.archive, name='blog-archive'), 11 | 12 | url(r'^(?P\d{4})/(?P\d{1,2})/(?P\d{1,2})/(?P[\w\-]*)/', 13 | views.post, name='blog-post'), 14 | url(r'^tag/(?P[\w\-]+)/$', views.tag, name='blog-tag'), 15 | url(r'^tag/(?P[\w\-]+)/(?P\d*)/$', views.tag, name='blog-tag'), 16 | url(r'^category/(?P[\w\-]+)/$', views.category, name='blog-category'), 17 | url(r'^category/(?P[\w\-]+)/(?P\d*)/$', views.category, name='blog-category'), 18 | 19 | url(r'^feed/$', BlogAtomFeed(), name='blog-feed'), 20 | url(r'^feed/rss/$', BlogFeed(), name='blog-rss-feed'), 21 | 22 | # rule for backwards compatibility with old site 23 | url(r'^archive[\-/].*[\-/](?P\d+)/?', views.moved, name='blog-moved'), 24 | ] -------------------------------------------------------------------------------- /djangopress/contact/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/contact/__init__.py -------------------------------------------------------------------------------- /djangopress/contact/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import MailAddress, MailLog 3 | 4 | class MailAddressAdmin(admin.ModelAdmin): 5 | list_display = ('name', 'email') 6 | 7 | admin.site.register(MailAddress, MailAddressAdmin) 8 | 9 | class MailLogAdmin(admin.ModelAdmin): 10 | list_display = ('subject', 'name', 'email', 'created_date') 11 | 12 | admin.site.register(MailLog, MailLogAdmin) -------------------------------------------------------------------------------- /djangopress/contact/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ] 11 | 12 | operations = [ 13 | migrations.CreateModel( 14 | name='MailAddress', 15 | fields=[ 16 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 17 | ('name', models.CharField(max_length=50)), 18 | ('email', models.CharField(max_length=100)), 19 | ], 20 | ), 21 | migrations.CreateModel( 22 | name='MailLog', 23 | fields=[ 24 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 25 | ('subject', models.CharField(max_length=200, verbose_name=b'Subject')), 26 | ('email', models.CharField(max_length=100, verbose_name=b'E-mail')), 27 | ('name', models.CharField(max_length=50, verbose_name=b'Name')), 28 | ('message', models.TextField(verbose_name=b'Message')), 29 | ('to', models.ForeignKey(verbose_name=b'To', to='contact.MailAddress', on_delete=models.CASCADE)), 30 | ], 31 | ), 32 | ] 33 | -------------------------------------------------------------------------------- /djangopress/contact/migrations/0002_auto_20170710_0953.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.3 on 2017-07-10 09:54 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | import django.db.models.deletion 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ('contact', '0001_initial'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AlterField( 17 | model_name='maillog', 18 | name='email', 19 | field=models.CharField(max_length=100, verbose_name='E-mail'), 20 | ), 21 | migrations.AlterField( 22 | model_name='maillog', 23 | name='message', 24 | field=models.TextField(verbose_name='Message'), 25 | ), 26 | migrations.AlterField( 27 | model_name='maillog', 28 | name='name', 29 | field=models.CharField(max_length=50, verbose_name='Name'), 30 | ), 31 | migrations.AlterField( 32 | model_name='maillog', 33 | name='subject', 34 | field=models.CharField(max_length=200, verbose_name='Subject'), 35 | ), 36 | migrations.AlterField( 37 | model_name='maillog', 38 | name='to', 39 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contact.MailAddress', verbose_name='To'), 40 | ), 41 | ] 42 | -------------------------------------------------------------------------------- /djangopress/contact/migrations/0003_maillog_created_date.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.3 on 2017-08-11 02:28 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | import django.utils.timezone 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ('contact', '0002_auto_20170710_0953'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AddField( 17 | model_name='maillog', 18 | name='created_date', 19 | field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now), 20 | preserve_default=False, 21 | ), 22 | ] 23 | -------------------------------------------------------------------------------- /djangopress/contact/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/contact/migrations/__init__.py -------------------------------------------------------------------------------- /djangopress/contact/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | class MailAddress(models.Model): 4 | name = models.CharField(max_length=50) 5 | email = models.CharField(max_length=100) 6 | 7 | def __str__(self): 8 | return self.name 9 | 10 | class MailLog(models.Model): 11 | subject = models.CharField(max_length=200, verbose_name="Subject") 12 | email = models.CharField(max_length=100, verbose_name="E-mail") 13 | name = models.CharField(max_length=50, verbose_name="Name") 14 | to = models.ForeignKey(MailAddress, verbose_name="To", on_delete=models.CASCADE) 15 | message = models.TextField(verbose_name="Message") 16 | created_date = models.DateTimeField(auto_now_add=True) 17 | 18 | def __str__(self): 19 | return self.subject -------------------------------------------------------------------------------- /djangopress/contact/templates/contact/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block content %} 3 | {% load field_form %} 4 | 5 |
    6 | {% if error %}

    {{ error }}

    {% endif %} 7 | {% csrf_token %} 8 |
    {% form form %} 9 |

    10 |
    11 |
    12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /djangopress/contact/tests.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file demonstrates two different styles of tests (one doctest and one 3 | unittest). These will both pass when you run "manage.py test". 4 | 5 | Replace these with more appropriate tests for your application. 6 | """ 7 | 8 | from django.test import TestCase 9 | 10 | class SimpleTest(TestCase): 11 | def test_basic_addition(self): 12 | """ 13 | Tests that 1 + 1 always equals 2. 14 | """ 15 | self.failUnlessEqual(1 + 1, 2) 16 | 17 | __test__ = {"doctest": """ 18 | Another way to test that 1 + 1 is equal to 2. 19 | 20 | >>> 1 + 1 == 2 21 | True 22 | """} 23 | 24 | -------------------------------------------------------------------------------- /djangopress/contact/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | from djangopress.contact import views 3 | 4 | urlpatterns = [ 5 | url(r'^$', views.contact, name='contact-index'), 6 | url(r'^thanks/$', views.thanks, name='contact-thanks'), 7 | ] 8 | -------------------------------------------------------------------------------- /djangopress/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/core/__init__.py -------------------------------------------------------------------------------- /djangopress/core/_dynamic.py: -------------------------------------------------------------------------------- 1 | 2 | class DynamicRegister(object): 3 | 4 | def __init__(self): 5 | self._modules = {} 6 | 7 | def __call__(self, name, func, mod): 8 | self._modules[name] = (func, mod) 9 | 10 | def get_modules(self): 11 | return self._modules 12 | 13 | register = DynamicRegister() -------------------------------------------------------------------------------- /djangopress/core/format/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/core/format/__init__.py -------------------------------------------------------------------------------- /djangopress/core/format/html.py: -------------------------------------------------------------------------------- 1 | from lxml import html 2 | 3 | class Library(object): 4 | tags = {} 5 | 6 | @classmethod 7 | def tag(cls, name=None, func=None): 8 | cls.tags[name] = func 9 | 10 | try: 11 | from pygments import highlight 12 | from pygments.lexers import get_lexer_by_name 13 | from pygments.formatters import HtmlFormatter 14 | 15 | def format_code(node): 16 | if not node.attrib.get('codelang'): 17 | return None 18 | lexer = get_lexer_by_name(node.attrib.get('codelang'), stripall=True) 19 | formatter = HtmlFormatter(linenos=True) 20 | code = node.text + ''.join(map(bytes.decode, (html.tostring(n) for n in node))) 21 | result = highlight(code, lexer, formatter) 22 | code_node = html.fromstring(result) 23 | return code_node 24 | 25 | Library.tag("//code", format_code) 26 | except ImportError: 27 | pass 28 | 29 | def extended_html(text, *args, **kwargs): 30 | nodes = html.fragment_fromstring(text, create_parent='div') 31 | for name, func in Library.tags.items(): 32 | for n in nodes.xpath(name): 33 | new = func(n) 34 | if new is not None: 35 | n.getparent().replace(n, new) 36 | return ''.join(map(bytes.decode, (html.tostring(node) for node in nodes))) -------------------------------------------------------------------------------- /djangopress/core/format/magic_html.py: -------------------------------------------------------------------------------- 1 | import re 2 | from .bbcode import Lexer, Parser 3 | from . import nodes 4 | from django.conf import settings 5 | 6 | TAG_START = "<" 7 | TAG_END = ">" 8 | 9 | class MagicLibrary(nodes.Library): 10 | tags = {} 11 | 12 | class HtmlLexer(Lexer): 13 | TAG_START = TAG_START 14 | TAG_END = TAG_END 15 | tag_re = re.compile('(%s.*?%s)' % (re.escape(TAG_START), re.escape(TAG_END)), re.DOTALL) 16 | 17 | class HtmlTagNode(nodes.TagNode): 18 | def render(self, context, **kwargs): 19 | return self.contents() 20 | 21 | class MagicHtmlParser(Parser): 22 | def parse_error(self, nodelist, token): 23 | self.extend_nodelist(nodelist, HtmlTagNode(token)) 24 | 25 | def image_tag(parser, token): 26 | kargs = nodes.tag_arguments(token.contents)[2] 27 | kargs["src"] = "%s/%s" % (settings.STATIC_URL.rstrip('/'), 28 | kargs.get("src").lstrip('/')) 29 | return nodes.AttrNode(token, node_name="img", kargs=kargs, closes=False, 30 | attrs=('src', 'width', 'height', 'title', 'alt')) 31 | MagicLibrary.tag("image", image_tag) 32 | 33 | def magic_html(text, context=None, *args, **kargs): 34 | lex = HtmlLexer(text) 35 | parse = MagicHtmlParser(lex.tokenize()) 36 | parse.tags = MagicLibrary 37 | return parse.parse().render(context) -------------------------------------------------------------------------------- /djangopress/core/format/models.py: -------------------------------------------------------------------------------- 1 | from importlib import import_module 2 | from django.conf import settings 3 | from django.utils.module_loading import module_has_submodule 4 | from . import nodes 5 | 6 | def autodiscover(): 7 | for app in settings.INSTALLED_APPS: 8 | mod = import_module(app) 9 | try: 10 | module = import_module('%s.format_tags' % app) 11 | # needed because we seem to get mutiple Library 12 | # objects in memory and this makes them all 13 | # form one 14 | nodes.Library.tags.update(module.library.tags) 15 | except: 16 | if module_has_submodule(mod, 'format_tags'): 17 | raise -------------------------------------------------------------------------------- /djangopress/core/format/smilies.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | import re 3 | 4 | smiles_info = [ 5 | ("emoticon-smile", [':-)', ':)', ':D', ':o)', ':]', ':3', ':c)', ':>', '=]', '8)', '=)', ':}', ':^)']), 6 | ("emoticon-unhappy", ['>:[', ':-(', ':(', ':-c', ':c', ':-<', ':<', ':-[', ':[', ':{']), 7 | ("emoticon-unhappy-wink", [";("]), 8 | ("emoticon-cry", [":'-(", ":'("]), 9 | ("emoticon-wink", [';-)', ';)', '*-)', '*)', ';-]', ';]', ';D', ';^)', ':-, ']), 10 | ("emoticon-tongue", ['>:P', ':-P', ':P', 'X-P', 'x-p', 'xp', 'XP', ':-p', ':p', '=p', ':-b', ':b', 'd:']), 11 | ("emoticon-surprise", ['>:O', ':-O', ':O', ':-o', ':o', '8-0', 'O_O', 'o-o', 'O_o', 'o_O', 'o_o', 'O-O']), 12 | ("emoticon-no-expression", [':|', ':-|']), 13 | ] 14 | 15 | 16 | 17 | smiles_re = [] 18 | for name, values in smiles_info: 19 | smiles_re.append((name, re.compile(r'(^|\s)(%s)(\s|$)' % '|'.join([re.escape(i) for i in values])))) 20 | 21 | def add_smilies(text, smilies=True): 22 | if not smilies: 23 | return text 24 | for name, regexp in smiles_re: 25 | text = regexp.sub(r' \2 ' % (settings.SMILIES_ICON_FOLDER, name), text) 26 | return text -------------------------------------------------------------------------------- /djangopress/core/format/stripped_html.py: -------------------------------------------------------------------------------- 1 | 2 | import lxml 3 | from lxml.html.clean import Cleaner 4 | 5 | def stripped_html(text, context=None, ids=None, *args, **kargs): 6 | doc = lxml.html.fromstring(text) 7 | cleaner = Cleaner() 8 | doc = cleaner.clean_html(doc) 9 | if ids: 10 | for id in ids: 11 | for bad in doc.xpath("//*[@id='%s']" % id): 12 | bad.getparent().remove(bad) 13 | return doc.text_content() 14 | -------------------------------------------------------------------------------- /djangopress/core/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ] 11 | 12 | operations = [ 13 | migrations.CreateModel( 14 | name='Property', 15 | fields=[ 16 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 17 | ('class_name', models.CharField(max_length=50, editable=False, db_index=True)), 18 | ('property', models.CharField(max_length=50)), 19 | ], 20 | options={ 21 | }, 22 | bases=(models.Model,), 23 | ), 24 | migrations.CreateModel( 25 | name='IntProperty', 26 | fields=[ 27 | ('property_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='core.Property', on_delete=models.CASCADE)), 28 | ('property_value', models.IntegerField()), 29 | ], 30 | options={ 31 | }, 32 | bases=('core.property',), 33 | ), 34 | migrations.CreateModel( 35 | name='CharProperty', 36 | fields=[ 37 | ('property_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='core.Property', on_delete=models.CASCADE)), 38 | ('property_value', models.CharField(max_length=255)), 39 | ], 40 | options={ 41 | }, 42 | bases=('core.property',), 43 | ), 44 | ] 45 | -------------------------------------------------------------------------------- /djangopress/core/migrations/0002_auto_20140928_1807.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('core', '0001_initial'), 11 | ] 12 | 13 | operations = [ 14 | migrations.RemoveField( 15 | model_name='charproperty', 16 | name='property_ptr', 17 | ), 18 | migrations.DeleteModel( 19 | name='CharProperty', 20 | ), 21 | migrations.RemoveField( 22 | model_name='intproperty', 23 | name='property_ptr', 24 | ), 25 | migrations.DeleteModel( 26 | name='IntProperty', 27 | ), 28 | migrations.RenameField( 29 | model_name='property', 30 | old_name='property', 31 | new_name='name', 32 | ), 33 | migrations.RemoveField( 34 | model_name='property', 35 | name='class_name', 36 | ), 37 | migrations.AddField( 38 | model_name='property', 39 | name='value', 40 | field=models.CharField(default='', max_length=1024), 41 | preserve_default=False, 42 | ), 43 | migrations.AddField( 44 | model_name='property', 45 | name='value_type', 46 | field=models.CharField(default='s', max_length=1, choices=[(b's', b'string'), (b'i', b'integer'), (b'b', b'boolean'), (b'f', b'float')]), 47 | preserve_default=False, 48 | ), 49 | ] 50 | -------------------------------------------------------------------------------- /djangopress/core/migrations/0003_auto_20140928_1906.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('core', '0002_auto_20140928_1807'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='property', 16 | name='value', 17 | field=models.TextField(), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /djangopress/core/migrations/0004_auto_20170710_0953.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.3 on 2017-07-10 09:54 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('core', '0003_auto_20140928_1906'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='property', 17 | name='value_type', 18 | field=models.CharField(choices=[('s', 'string'), ('i', 'integer'), ('b', 'boolean'), ('f', 'float')], max_length=1), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /djangopress/core/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/core/migrations/__init__.py -------------------------------------------------------------------------------- /djangopress/core/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | 5 | class Property(models.Model): 6 | name = models.CharField(max_length=50) 7 | value = models.TextField() 8 | value_type = models.CharField(max_length=1, choices=(('s','string'),('i','integer'),('b','boolean'), ('f', 'float'))) 9 | 10 | def actual_value(self): 11 | types = { 12 | 's': str, 13 | 'i': int, 14 | 'f': float, 15 | 'b': (lambda v: v.lower().startswith('t') or v.startswith('1')) 16 | } 17 | return types[self.value_type](self.value) -------------------------------------------------------------------------------- /djangopress/core/sitemap.py: -------------------------------------------------------------------------------- 1 | 2 | class SitemapRegister(object): 3 | 4 | def __init__(self): 5 | self._sitemaps = {} 6 | 7 | def __call__(self, name, cls): 8 | self._sitemaps[name] = cls 9 | 10 | def get_sitemaps(self): 11 | return self._sitemaps 12 | 13 | register = SitemapRegister() 14 | 15 | def autodiscover(): 16 | "based on the admin site autodiscover see that for more info" 17 | import copy 18 | from django.conf import settings 19 | from importlib import import_module 20 | from django.utils.module_loading import module_has_submodule 21 | 22 | for app in settings.INSTALLED_APPS: 23 | mod = import_module(app) 24 | try: 25 | before_import_registry = copy.copy(register._sitemaps) 26 | import_module('%s.sitemaps' % app) 27 | except: 28 | register._sitemaps = before_import_registry 29 | if module_has_submodule(mod, 'sitemaps'): 30 | raise 31 | -------------------------------------------------------------------------------- /djangopress/core/static/css/search.css: -------------------------------------------------------------------------------- 1 | /* try and keep this matching the style of the blog entries */ 2 | 3 | #search-fields input[type="search"]{ 4 | width:50%; 5 | } 6 | 7 | #search-header h3 { 8 | float:left; 9 | } 10 | 11 | #search-header .pagination { 12 | float:right; 13 | text-align:right; 14 | padding:1.25em 0; 15 | } 16 | 17 | #search-results { 18 | clear:both; 19 | list-style-type:none; 20 | } 21 | 22 | #search-results h3 { 23 | padding:0; 24 | margin:1em 0 0; 25 | font-size:1.125em; 26 | } 27 | 28 | #search-results small { 29 | font-size:0.675em; 30 | color:#98bc55; 31 | text-align:right; 32 | display:block; 33 | } 34 | 35 | 36 | #search-results p { 37 | margin:0; 38 | } 39 | 40 | #search-results p .highlighted { 41 | font-weight:bold; 42 | color:#fff; 43 | } 44 | 45 | #search-results h3 a { 46 | text-decoration:none; 47 | } 48 | 49 | #search-results .result-link { 50 | font-size:0.675em; 51 | color:#98bc55; 52 | } -------------------------------------------------------------------------------- /djangopress/core/templates/core/field_form.html: -------------------------------------------------------------------------------- 1 | {% load field_form %} 2 | {{ form.non_field_errors }} 3 | {% for legend, fields in fieldsets %} 4 |
    5 | {{ legend }} 6 | {% for field in fields %} 7 |
    8 | {% if field.errors %} 9 |
    {{ field.errors }}
    10 | {% endif %} 11 | {% if field.field.widget|is_checkbox %} 12 | {{ field }} {{ field.label_tag }} 13 | {% else %} 14 | {% if field.label %}{{ field.label_tag }} {% endif %}{{ field }} 15 | {% endif %} 16 | {% if field.help_text %} 17 |
    {{ field.help_text }}
    18 | {% endif %} 19 |
    20 | {% endfor %} 21 |
    22 | {% endfor %} 23 | {% if form.hidden_fields %} 24 | {% for field in form.hidden_fields %} 25 | {{ field }} 26 | {% endfor %} 27 | {% endif %} -------------------------------------------------------------------------------- /djangopress/core/templates/core/form.html: -------------------------------------------------------------------------------- 1 | {% load field_form %} 2 | {{ form.non_field_errors }} 3 | {% for field in form %} 4 | {% if field.is_hidden %} 5 | {{ field }} 6 | {% else %} 7 |
    8 | {% if field.errors %} 9 |
    {{ field.errors }}
    10 | {% endif %} 11 | {% if field.field.widget|is_checkbox %} 12 | {{ field }} {{ field.label_tag }} 13 | {% else %} 14 | {{ field.label_tag }} {{ field }} 15 | {% endif %} 16 | {% if field.help_text %} 17 |
    {{ field.help_text }}
    18 | {% endif %} 19 |
    20 | {% endif %} 21 | {% endfor %} -------------------------------------------------------------------------------- /djangopress/core/templates/core/pagination.html: -------------------------------------------------------------------------------- 1 | {% load show_pagination %} 2 | 3 | {% if pages %} 4 | 32 | {% endif %} -------------------------------------------------------------------------------- /djangopress/core/templates/core/pagination_query.html: -------------------------------------------------------------------------------- 1 | {% load show_pagination %} 2 | 3 | {% if pages %} 4 | 34 | {% endif %} -------------------------------------------------------------------------------- /djangopress/core/templates/core/simple_pagination.html: -------------------------------------------------------------------------------- 1 | {% load show_pagination %} 2 | 3 | {% if pages %} 4 | 17 | {% endif %} -------------------------------------------------------------------------------- /djangopress/core/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/core/templatetags/__init__.py -------------------------------------------------------------------------------- /djangopress/core/templatetags/field_form.py: -------------------------------------------------------------------------------- 1 | from django.forms import fields 2 | from django import forms 3 | 4 | from django import template 5 | register = template.Library() 6 | 7 | @register.inclusion_tag('core/form.html') 8 | def form(form): 9 | return { 10 | "form": form 11 | } 12 | 13 | @register.filter(name='is_checkbox') 14 | def is_checkbox(value): 15 | return isinstance(value, fields.CheckboxInput) 16 | 17 | @register.filter(name='is_textarea') 18 | def is_textarea(value): 19 | return isinstance(value, forms.Textarea) 20 | 21 | @register.inclusion_tag('core/field_form.html') 22 | def field_form(form): 23 | fieldsets = [] 24 | fields_map = dict((field.name, field) for field in form) 25 | form_fields = [] 26 | for legend, fields in form.fieldsets: 27 | try: 28 | set_fields = [fields_map.get(field) for field in fields] 29 | fieldsets.append((legend, set_fields)) 30 | form_fields.extend(set_fields) 31 | except: 32 | pass 33 | return { 34 | "form": form, 35 | "fieldsets": fieldsets, 36 | "fields": form_fields, 37 | } 38 | -------------------------------------------------------------------------------- /djangopress/core/templatetags/smart_truncate_chars.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | from djangopress.core.util import smart_truncate_chars as _smart_truncate_chars 3 | 4 | register = template.Library() 5 | 6 | # truncate chars but leaving last word complete 7 | @register.filter(name='smarttruncatechars') 8 | def smart_truncate_chars(value, max_length): 9 | return _smart_truncate_chars(value, max_length) -------------------------------------------------------------------------------- /djangopress/core/tests.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file demonstrates two different styles of tests (one doctest and one 3 | unittest). These will both pass when you run "manage.py test". 4 | 5 | Replace these with more appropriate tests for your application. 6 | """ 7 | 8 | from django.test import TestCase 9 | 10 | class SimpleTest(TestCase): 11 | def test_basic_addition(self): 12 | """ 13 | Tests that 1 + 1 always equals 2. 14 | """ 15 | self.failUnlessEqual(1 + 1, 2) 16 | 17 | __test__ = {"doctest": """ 18 | Another way to test that 1 + 1 is equal to 2. 19 | 20 | >>> 1 + 1 == 2 21 | True 22 | """} 23 | 24 | -------------------------------------------------------------------------------- /djangopress/core/util.py: -------------------------------------------------------------------------------- 1 | 2 | from django.conf import settings 3 | from django.contrib.auth.models import Group 4 | 5 | ANONYMOUS_USER_GROUP = getattr(settings, 'ANONYMOUS_USER_GROUP', None) 6 | 7 | def get_client_ip(request): 8 | x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') 9 | if x_forwarded_for: 10 | return x_forwarded_for.split(',')[-1].strip() 11 | return request.META.get('REMOTE_ADDR') 12 | 13 | def has_permission(request, app, name): 14 | if request.user.is_authenticated(): 15 | return request.user.has_perm('%s.%s' % (app, name)) 16 | elif ANONYMOUS_USER_GROUP: 17 | group = Group.objects.get(name=ANONYMOUS_USER_GROUP) 18 | return bool(group.permissions.filter(codename=name)) 19 | return False 20 | 21 | def choose_form(request, authenticated, anonymous, *args, **kargs): 22 | if request.user.is_authenticated(): 23 | return authenticated(*args, **kargs) 24 | return anonymous(*args, **kargs) 25 | 26 | def smart_truncate_chars(value, max_length): 27 | max_length = int(max_length) 28 | if len(value) > max_length: 29 | # limits the number of characters in value to max_length (blunt cut) 30 | truncd_val = value[:max_length] 31 | # check if the next upcoming character after the limit is not a space, 32 | # in which case it might be a word continuing 33 | if value[max_length] != ' ': 34 | # rfind will return the last index where matching the searched character, 35 | # in this case we are looking for the last space 36 | # then we only return the number of character up to that last space 37 | truncd_val = truncd_val[:truncd_val.rfind(' ')] 38 | return truncd_val + '...' 39 | return value 40 | -------------------------------------------------------------------------------- /djangopress/core/views.py: -------------------------------------------------------------------------------- 1 | # Create your views here. 2 | -------------------------------------------------------------------------------- /djangopress/donate/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/donate/__init__.py -------------------------------------------------------------------------------- /djangopress/donate/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from djangopress.donate.models import Donation 3 | 4 | class DonationAdmin(admin.ModelAdmin): 5 | list_display = ('name', 'date', 'amount', 'validated') 6 | admin.site.register(Donation, DonationAdmin) -------------------------------------------------------------------------------- /djangopress/donate/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | import datetime 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('ipn', '__first__'), 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='Donation', 17 | fields=[ 18 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 19 | ('name', models.CharField(max_length=50)), 20 | ('date', models.DateField(default=datetime.datetime.today)), 21 | ('amount', models.FloatField(default=0, blank=True)), 22 | ('link_url', models.URLField(null=True, blank=True)), 23 | ('link_text', models.CharField(max_length=50, null=True, blank=True)), 24 | ('validated', models.BooleanField(default=False)), 25 | ('invoice_id', models.CharField(max_length=50, null=True, blank=True)), 26 | ('payment', models.ForeignKey(blank=True, to='ipn.PayPalIPN', null=True, on_delete=models.CASCADE)), 27 | ], 28 | options={ 29 | }, 30 | bases=(models.Model,), 31 | ), 32 | ] 33 | -------------------------------------------------------------------------------- /djangopress/donate/migrations/0002_auto_20140909_0456.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('donate', '0001_initial'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='donation', 16 | name='amount', 17 | field=models.DecimalField(default=0, max_digits=6, decimal_places=2, blank=True), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /djangopress/donate/migrations/0003_auto_20141109_2155.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('donate', '0002_auto_20140909_0456'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='donation', 16 | name='link_text', 17 | field=models.CharField(max_length=50, null=True, verbose_name=b'Link Text (optional)', blank=True), 18 | ), 19 | migrations.AlterField( 20 | model_name='donation', 21 | name='link_url', 22 | field=models.URLField(null=True, verbose_name=b'Link Url (optional)', blank=True), 23 | ), 24 | ] 25 | -------------------------------------------------------------------------------- /djangopress/donate/migrations/0004_auto_20170710_0959.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.3 on 2017-07-10 09:59 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('donate', '0003_auto_20141109_2155'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='donation', 17 | name='link_text', 18 | field=models.CharField(blank=True, max_length=50, null=True, verbose_name='Link Text (optional)'), 19 | ), 20 | migrations.AlterField( 21 | model_name='donation', 22 | name='link_url', 23 | field=models.URLField(blank=True, null=True, verbose_name='Link Url (optional)'), 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /djangopress/donate/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/donate/migrations/__init__.py -------------------------------------------------------------------------------- /djangopress/donate/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from paypal.standard.ipn.signals import valid_ipn_received 3 | from paypal.standard.ipn.models import PayPalIPN 4 | import datetime 5 | 6 | class Donation(models.Model): 7 | name = models.CharField(max_length=50) 8 | date = models.DateField(default=datetime.datetime.today) 9 | amount = models.DecimalField(blank=True, default=0, max_digits=6, decimal_places=2) 10 | link_url = models.URLField(blank=True, null=True, verbose_name="Link Url (optional)") 11 | link_text = models.CharField(max_length=50, blank=True, null=True, verbose_name="Link Text (optional)") 12 | validated = models.BooleanField(default=False) 13 | invoice_id = models.CharField(max_length=50, null=True, blank=True) 14 | payment = models.ForeignKey(PayPalIPN, null=True, blank=True, on_delete=models.CASCADE) 15 | 16 | def should_link(self): 17 | if self.amount >= 20: 18 | return True 19 | elif self.amount >= 10: 20 | today = datetime.date.today() 21 | if self.date > datetime.date(today.year - 2, today.month, today.day): 22 | return True 23 | return False 24 | 25 | def update_donation(sender, **kwargs): 26 | ipn_obj = sender 27 | if ipn_obj.payment_status == "Completed": 28 | # Undertake some action depending upon `ipn_obj`. 29 | try: 30 | donation = Donation.objects.get(invoice_id=ipn_obj.invoice) 31 | except Donation.DoesNotExist: 32 | return 33 | donation.validated = True 34 | donation.amount = ipn_obj.mc_gross 35 | donation.payment = ipn_obj 36 | donation.save() 37 | else: 38 | pass # not a good payment 39 | valid_ipn_received.connect(update_donation) -------------------------------------------------------------------------------- /djangopress/donate/templates/donate/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block content %} 3 | {% load field_form %} 4 |

    Donating

    5 |

    6 | Donations support my continued efforts to create quality add-ons, icons and other content. It covers in part the the costs and time spent working on my software. I do what I do because of the pleasure and satisfaction I receive from it. But receiveing something in return makes in even more worth while, so I ask you to donate and be generious to this university student. 7 |

    8 | 9 |

    10 | To donate, just press the button below, or if you want to be added to the list of people who have donated, please fill in the form first. 11 |

    12 | 13 | {{ form.render }} 14 | 15 |
    16 | {% csrf_token %} 17 |
    {% form donate %} 18 |

    19 |
    20 |
    21 | 22 |

    Past Donors

    23 | 24 |

    25 | A list of people that I would really like to thank for donating. 26 |

    27 | 28 | 29 | {% for donation in donations %} 30 | 31 | 32 | 33 | 34 | 35 | {% endfor %} 36 |
    {% if donation.link_url and donation.should_link %}{{ donation.link_text }} {% else %}{{ donation.name }}{% endif %}${{ donation.amount }}{{ donation.date }}
    37 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/donate/templates/donate/list.html: -------------------------------------------------------------------------------- 1 |
      2 | {% for donation in donations %} 3 |
    • ${{ donation.amount }} {% if donation.link_url and donation.amount >= 10 %}{{ donation.link_text }} {% else %}{{ donation.name }}{% endif %}
    • 4 | {% endfor %} 5 |
    -------------------------------------------------------------------------------- /djangopress/donate/templates/donate/process.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block content %} 3 |

    4 | Please now press the below button to be redirected over to PayPal to make the donation. 5 |

    6 | {{ form.render }} 7 | {% endblock %} 8 | -------------------------------------------------------------------------------- /djangopress/donate/templates/donate/thanks.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block content %} 3 |

    Thanks for Donating!

    4 |

    5 | Many thanks for donating to help support Codefisher.org. Thought the words I write might mean little, feel sure I would come and shake your hand to express my thanks if that was possible. 6 |

    7 | {% endblock %} 8 | -------------------------------------------------------------------------------- /djangopress/donate/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/donate/templatetags/__init__.py -------------------------------------------------------------------------------- /djangopress/donate/templatetags/donate_tags.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | from djangopress.donate.models import Donation 3 | 4 | register = template.Library() 5 | 6 | @register.inclusion_tag('donate/list.html') 7 | def show_latest_donations(number=5): 8 | try: 9 | number = int(number) 10 | except ValueError: 11 | number = 5 12 | donations = Donation.objects.filter(validated=True).order_by('-date', '-amount')[0:number] 13 | return { 14 | "donations": donations, 15 | "nofollow": True, 16 | } 17 | 18 | @register.inclusion_tag('donate/list.html') 19 | def show_best_donations(number=5): 20 | try: 21 | number = int(number) 22 | except ValueError: 23 | number = 5 24 | donations = Donation.objects.filter(validated=True).order_by('-amount', '-date')[0:number] 25 | return { 26 | "donations": donations, 27 | "nofollow": True, 28 | } -------------------------------------------------------------------------------- /djangopress/donate/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /djangopress/donate/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | from djangopress.donate import views 3 | 4 | urlpatterns = [ 5 | url(r'^$', views.index, name='donate-index'), 6 | url(r'^thanks$', views.thanks, name='donate-thanks'), 7 | ] 8 | -------------------------------------------------------------------------------- /djangopress/dump.sh: -------------------------------------------------------------------------------- 1 | python ../manage.py dumpdata --indent 2 blog > ../fixtures/blog.json 2 | python ../manage.py dumpdata --indent 2 forum > ../fixtures/forum.json 3 | python ../manage.py dumpdata --indent 2 menus > ../fixtures/links.json 4 | python ../manage.py dumpdata --indent 2 sites > ../fixtures/sites.json 5 | python ../manage.py dumpdata --indent 2 accounts auth contenttypes > ../fixtures/auth.json 6 | python ../manage.py dumpdata --indent 2 pages > ../fixtures/pages.json 7 | python ../manage.py dumpdata --indent 2 downloads extension_downloads > ../fixtures/downloads.json 8 | python ../manage.py dumpdata --indent 2 donate ipn > ../fixtures/donate.json 9 | -------------------------------------------------------------------------------- /djangopress/files/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/files/__init__.py -------------------------------------------------------------------------------- /djangopress/files/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from djangopress.files.models import UploadedFile 3 | from django.contrib.sites.models import Site 4 | 5 | class UploadAdmin(admin.ModelAdmin): 6 | list_display = ('upload', 'upload_url', 'description', 'date') 7 | 8 | def upload_url(self, upload): 9 | site = Site.objects.get_current() 10 | path = "http://{0}{1}".format(site.domain, upload.upload.url) 11 | return '{1}'.format(upload.upload.url, path) 12 | upload_url.allow_tags = True 13 | 14 | admin.site.register(UploadedFile, UploadAdmin) 15 | -------------------------------------------------------------------------------- /djangopress/files/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ] 11 | 12 | operations = [ 13 | migrations.CreateModel( 14 | name='UploadedFile', 15 | fields=[ 16 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 17 | ('upload', models.FileField(upload_to=b'files')), 18 | ('date', models.DateTimeField(auto_now_add=True)), 19 | ('description', models.TextField(null=True, blank=True)), 20 | ], 21 | ), 22 | ] 23 | -------------------------------------------------------------------------------- /djangopress/files/migrations/0002_auto_20150805_0726.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('files', '0001_initial'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='uploadedfile', 16 | name='upload', 17 | field=models.FileField(upload_to=b'files/%y/%m'), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /djangopress/files/migrations/0003_auto_20170710_0953.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.3 on 2017-07-10 09:54 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('files', '0002_auto_20150805_0726'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='uploadedfile', 17 | name='upload', 18 | field=models.FileField(upload_to='files/%y/%m'), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /djangopress/files/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/files/migrations/__init__.py -------------------------------------------------------------------------------- /djangopress/files/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class UploadedFile(models.Model): 5 | upload = models.FileField(upload_to="files/%y/%m") 6 | date = models.DateTimeField(auto_now_add=True) 7 | description = models.TextField(null=True, blank=True) 8 | 9 | def get_absolute_url(self): 10 | return self.upload.url -------------------------------------------------------------------------------- /djangopress/files/tests.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file demonstrates writing tests using the unittest module. These will pass 3 | when you run "manage.py test". 4 | 5 | Replace this with more appropriate tests for your application. 6 | """ 7 | 8 | from django.test import TestCase 9 | 10 | 11 | class SimpleTest(TestCase): 12 | def test_basic_addition(self): 13 | """ 14 | Tests that 1 + 1 always equals 2. 15 | """ 16 | self.assertEqual(1 + 1, 2) 17 | -------------------------------------------------------------------------------- /djangopress/files/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | from .views import upload 3 | 4 | urlpatterns = [ 5 | url(r'^upload/$', upload, name='files-upload'), 6 | ] 7 | -------------------------------------------------------------------------------- /djangopress/files/views.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from django.http import HttpResponse 3 | 4 | from django.utils.html import escapejs 5 | from django.views.decorators.csrf import csrf_exempt 6 | from .models import UploadedFile 7 | 8 | class ImageForm(forms.ModelForm): 9 | class Meta: 10 | model = UploadedFile 11 | fields = ("upload", ) 12 | 13 | @csrf_exempt 14 | def upload(request): 15 | if request.user.is_authenticated() and request.user.is_staff: 16 | form = ImageForm(request.POST, request.FILES) 17 | if form.is_valid(): 18 | image = form.save() 19 | return HttpResponse("".format(image.get_absolute_url())) 20 | return HttpResponse("".format(escapejs('\n'.join([v[0] for k, v in form.errors.items()])))) 21 | else: 22 | return HttpResponse("") 23 | -------------------------------------------------------------------------------- /djangopress/forum/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/forum/__init__.py -------------------------------------------------------------------------------- /djangopress/forum/management/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/forum/management/__init__.py -------------------------------------------------------------------------------- /djangopress/forum/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/forum/management/commands/__init__.py -------------------------------------------------------------------------------- /djangopress/forum/management/commands/forum_clear_spam.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | from django.core.management.base import BaseCommand 5 | from djangopress.forum.models import Thread, Post, Forum 6 | import time 7 | import akismet 8 | from django.conf import settings 9 | from django.utils.encoding import force_str 10 | 11 | 12 | class Command(BaseCommand): 13 | help = 'Check if any posts are spam and marks them as such' 14 | 15 | def handle(self, *args, **options): 16 | Post.objects.filter(is_spam=True).delete() 17 | # now there might be threads without any posts 18 | for thread in Thread.objects.all(): 19 | if Post.objects.filter(thread=thread.pk).count() == 0: 20 | thread.delete() 21 | print("Spam posts deleted") -------------------------------------------------------------------------------- /djangopress/forum/management/commands/forum_fix_counts.py: -------------------------------------------------------------------------------- 1 | from django.core.management.base import BaseCommand 2 | from djangopress.forum.models import Thread, Post, Forum 3 | 4 | class Command(BaseCommand): 5 | help = 'Fixes the counts on threads and forums' 6 | 7 | def handle(self, *args, **options): 8 | for thread in Thread.objects.all(): 9 | Thread.objects.filter(pk=thread.pk).update(num_posts=Post.objects.filter(thread=thread.pk, is_spam=False, is_public=True).count()) 10 | for forum in Forum.objects.all(): 11 | try: 12 | Forum.objects.filter(pk=forum.pk).update(num_posts=Post.objects.filter(thread__forum=forum.pk, is_spam=False, is_public=True).count()) 13 | Forum.objects.filter(pk=forum.pk).update(num_threads=Thread.objects.filter(forum=forum.pk).exclude(last_post=None).count()) 14 | except: 15 | pass # empty forum -------------------------------------------------------------------------------- /djangopress/forum/management/commands/forum_fix_refs.py: -------------------------------------------------------------------------------- 1 | from django.core.management.base import BaseCommand 2 | from djangopress.forum.models import Thread, Post, Forum 3 | 4 | class Command(BaseCommand): 5 | help = 'Fixes the last and first post on threads and forums' 6 | 7 | def handle(self, *args, **options): 8 | #fix Thread first_post, last_post, last_post_date, 9 | #fix Forum last_post 10 | for thread in Thread.objects.all(): 11 | Thread.objects.filter(pk=thread.pk).update(first_post=Post.objects.filter(thread=thread.pk, is_spam=False, is_public=True).order_by('posted')[0]) 12 | Thread.objects.filter(pk=thread.pk).update(last_post=Post.objects.filter(thread=thread.pk, is_spam=False, is_public=True).order_by('-posted')[0]) 13 | for forum in Forum.objects.all(): 14 | try: 15 | Forum.objects.filter(pk=forum.pk).update(last_post=Post.objects.filter(thread__forum=forum.pk, is_spam=False, is_public=True).order_by('-posted')[0]) 16 | except: 17 | pass # empty forum 18 | -------------------------------------------------------------------------------- /djangopress/forum/migrations/0002_auto_20140927_1231.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('forum', '0001_initial'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='post', 16 | name='ip', 17 | field=models.GenericIPAddressField(), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /djangopress/forum/migrations/0003_auto_20140928_1817.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('core', '0002_auto_20140928_1807'), 11 | ('forum', '0002_auto_20140927_1231'), 12 | ] 13 | 14 | operations = [ 15 | migrations.RemoveField( 16 | model_name='forumgroup', 17 | name='properties', 18 | ), 19 | migrations.AddField( 20 | model_name='forumgroup', 21 | name='property', 22 | field=models.ForeignKey(blank=True, to='core.Property', null=True, on_delete=models.CASCADE), 23 | preserve_default=True, 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /djangopress/forum/migrations/0004_auto_20140928_1827.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('core', '0002_auto_20140928_1807'), 11 | ('forum', '0003_auto_20140928_1817'), 12 | ] 13 | 14 | operations = [ 15 | migrations.RemoveField( 16 | model_name='forumgroup', 17 | name='property', 18 | ), 19 | migrations.AddField( 20 | model_name='forumgroup', 21 | name='properties', 22 | field=models.ManyToManyField(to='core.Property', null=True, blank=True), 23 | preserve_default=True, 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /djangopress/forum/migrations/0005_auto_20140928_1852.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('core', '0002_auto_20140928_1807'), 11 | ('forum', '0004_auto_20140928_1827'), 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='ForumProperty', 17 | fields=[ 18 | ('property_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='core.Property', on_delete=models.CASCADE)), 19 | ('forums', models.ForeignKey(related_name=b'property', to='forum.ForumGroup', on_delete=models.CASCADE)), 20 | ], 21 | options={ 22 | }, 23 | bases=('core.property',), 24 | ), 25 | migrations.RemoveField( 26 | model_name='forumgroup', 27 | name='properties', 28 | ), 29 | ] 30 | -------------------------------------------------------------------------------- /djangopress/forum/migrations/0006_auto_20140928_1906.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('forum', '0005_auto_20140928_1852'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='forumproperty', 16 | name='forums', 17 | field=models.ForeignKey(related_name=b'properties', to='forum.ForumGroup', on_delete=models.CASCADE), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /djangopress/forum/migrations/0008_auto_20141005_1948.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('forum', '0007_auto_20140928_1940'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='forumgroup', 16 | name='format', 17 | field=models.CharField(max_length=20, choices=[(b'magic_html', b'Magic HTML'), (b'markdown', b'Markdown'), (b'bbcode', b'BBcode'), (b'sanitized_html', b'Sanitized HTML'), (b'plain_text', b'Plain Text'), (b'html', b'HTML'), (b'template', b'Django Template'), (b'restructuredtext', b'reStructuredText')]), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /djangopress/forum/migrations/0009_forumgroup_post_redirect_delay.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('forum', '0008_auto_20141005_1948'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='forumgroup', 16 | name='post_redirect_delay', 17 | field=models.IntegerField(default=3, help_text=b'How long to show the successful post page, before redirecting. Set to 0 to disable.'), 18 | preserve_default=True, 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /djangopress/forum/migrations/0010_auto_20150426_1817.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('forum', '0009_forumgroup_post_redirect_delay'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='forumgroup', 16 | name='format', 17 | field=models.CharField(max_length=20, choices=[(b'extended_html', b'Extended HTML'), (b'magic_html', b'Magic HTML'), (b'markdown', b'Markdown'), (b'bbcode', b'BBcode'), (b'sanitized_html', b'Sanitized HTML'), (b'plain_text', b'Plain Text'), (b'html', b'HTML'), (b'template', b'Django Template'), (b'restructuredtext', b'reStructuredText')]), 18 | ), 19 | migrations.AlterField( 20 | model_name='post', 21 | name='poster_email', 22 | field=models.EmailField(max_length=254, null=True, blank=True), 23 | ), 24 | migrations.AlterField( 25 | model_name='thread', 26 | name='poster_email', 27 | field=models.EmailField(max_length=254, null=True, blank=True), 28 | ), 29 | ] 30 | -------------------------------------------------------------------------------- /djangopress/forum/migrations/0011_auto_20150426_1821.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | from django.conf import settings 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('forum', '0010_auto_20150426_1817'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='forum', 17 | name='subscriptions', 18 | field=models.ManyToManyField(related_name='forum_forum_subscriptions', to=settings.AUTH_USER_MODEL, blank=True), 19 | ), 20 | migrations.AlterField( 21 | model_name='thread', 22 | name='subscriptions', 23 | field=models.ManyToManyField(related_name='forum_subscriptions', to=settings.AUTH_USER_MODEL, blank=True), 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /djangopress/forum/migrations/0013_auto_20170810_0859.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.3 on 2017-08-10 08:59 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('forum', '0012_auto_20170710_0959'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='post', 17 | name='user_agent', 18 | field=models.CharField(blank=True, default='', max_length=255, null=True), 19 | ), 20 | migrations.AlterField( 21 | model_name='forumgroup', 22 | name='format', 23 | field=models.CharField(choices=[('markdown', 'Markdown'), ('magic_html', 'Magic HTML'), ('extended_html', 'Extended HTML'), ('sanitized_html', 'Sanitized HTML'), ('template', 'Django Template'), ('html', 'HTML'), ('bbcode', 'BBcode'), ('plain_text', 'Plain Text')], max_length=20), 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /djangopress/forum/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/forum/migrations/__init__.py -------------------------------------------------------------------------------- /djangopress/forum/search.py: -------------------------------------------------------------------------------- 1 | from djangopress.core.search import ModelSetSearchView 2 | from djangopress.forum.views import get_forum 3 | 4 | class ForumSearchView(ModelSetSearchView): 5 | 6 | def __init__(self, *args, **kwargs): 7 | self.forums = None 8 | super(ForumSearchView, self).__init__(*args, **kwargs) 9 | 10 | def __call__(self, request, forums_slug, *args, **kwargs): 11 | self.forums = get_forum(forums_slug) 12 | return super(ForumSearchView, self).__call__(request) 13 | 14 | def extra_context(self): 15 | return { 16 | 'forums': self.forums, 17 | } -------------------------------------------------------------------------------- /djangopress/forum/search_indexes.py: -------------------------------------------------------------------------------- 1 | from haystack import indexes 2 | from djangopress.forum.models import Post 3 | from djangopress.core.format.stripped_html import stripped_html 4 | 5 | 6 | class PostIndex(indexes.SearchIndex, indexes.Indexable): 7 | text = indexes.CharField(model_attr='message', document=True, use_template=True) 8 | author = indexes.CharField(model_attr='author_name') 9 | pub_date = indexes.DateTimeField(model_attr='posted') 10 | title = indexes.CharField(model_attr='thread__subject', boost=1.5) 11 | 12 | def get_model(self): 13 | return Post 14 | 15 | def index_queryset(self, using=None): 16 | return self.get_model().objects.filter(is_spam=False, is_public=True) 17 | 18 | def prepare(self, obj): 19 | data = super(PostIndex, self).prepare(obj) 20 | data['text'] = stripped_html(data['text']) 21 | if obj.thread.sticky and obj == obj.thread.first_post: 22 | data['boost'] = 1.5 23 | else: 24 | data['boost'] = 0.75 25 | return data 26 | -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/email/forum_subscription_notification.txt: -------------------------------------------------------------------------------- 1 | {{ user.username|safe }}, 2 | 3 | {{ thread.author_name|safe }} has just posted a new thread title "{{ thread.subject|safe }}" in the forum "{{ thread.forum.name|safe }}" that you are subscribed to. 4 | 5 | The thread can be found here: 6 | {{ scheme }}://{{ site.domain }}{{ thread.get_absolute_url|safe }} 7 | 8 | Regards, 9 | 10 | The {{ forums.name|safe }} team. 11 | {{ scheme }}://{{ site.domain }}{{ forums.get_absolute_url|safe }} 12 | -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/email/subscription_notification.txt: -------------------------------------------------------------------------------- 1 | {{ user.username|safe }}, 2 | 3 | {{ post.author_name|safe }} has just posted a reply to a thread that you have subscribed to titled "{{ thread.subject|safe }}". 4 | 5 | The post can be found here: 6 | {{ scheme }}://{{ site.domain }}{{ post.get_absolute_url|safe }} 7 | 8 | There may be more replies to this thread, but only 1 email is sent per board visit for each subscribed thread. This is 9 | to limit the amount of mail that is sent to your inbox. 10 | 11 | Unsubscribing: 12 | -------------- 13 | 14 | You can unsubscribe at any time by logging into your profile and clicking on the "View Subscriptions" link. 15 | 16 | Regards, 17 | 18 | The {{ forums.name|safe }} team. 19 | {{ scheme }}://{{ site.domain }}{{ forums.get_absolute_url|safe }} 20 | -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/forum.html: -------------------------------------------------------------------------------- 1 | {% extends "forum/base.html" %} 2 | {% load show_pagination %} 3 | 4 | {% block content %} 5 | 6 | 11 |
    12 | {% simple_pagination threads forum %} 13 |
    14 |
    15 |

    Post new Thread

    16 |
    17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | {% for thread in threads %} 28 | 29 | 34 | 35 | 36 | 37 | 38 | {% endfor %} 39 | 40 |
    TopicRepliesViewsLast post
    30 | {% if thread.sticky %}Sticky: {% endif %} 31 | {% if thread.closed %}Closed: {% endif %} 32 | {{ thread.subject }} by {{ thread.author_name }} 33 | {{ thread.num_posts|add:-1 }}{{ thread.num_views }}{{ thread.last_post.posted }} by {{ thread.last_post.author_name }}
    41 |
    42 | {% simple_pagination threads forum %} 43 |
    44 |
    45 |

    Post new Thread

    46 |
    47 | {% endblock %} 48 | -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/post/action.html: -------------------------------------------------------------------------------- 1 | {% extends "forum/base.html" %} 2 | 3 | {% block content %} 4 | {% include "forum/post/crumbs.html" %} 5 |

    {{ name }}

    6 |
    7 |

    Are you sure you want to {{ message }}.

    8 | {% csrf_token %} 9 |

    10 |
    11 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/post/actions.html: -------------------------------------------------------------------------------- 1 | {% for action in actions %} 2 | {% if not forloop.first %} • {% endif %} 3 | {{ action.name }} 4 | {% endfor %} 5 | -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/post/crumbs.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/post/edit.html: -------------------------------------------------------------------------------- 1 | {% extends "forum/base.html" %} 2 | 3 | {% block content %} 4 | {% include "forum/post/crumbs.html" %} 5 |
    6 | {% csrf_token %} 7 |
    8 | Message 9 | {{ thread_form.as_p }} 10 | {{ edit_form.non_field_errors }} 11 |
    12 | {% if edit_form.message.errors %} 13 |
    {{ edit_form.message.errors }}
    14 | {% endif %} 15 | {{ edit_form.message.label_tag }} {{ edit_form.message }} 16 |
    17 |
    18 | Format: {{ post.get_format.name }}. Images: {{ forums.display_images|yesno }}. Smilies {{ forums.show_smilies|yesno }}. 19 |
    20 |
    21 | {% if edit_form.edit_reason.errors %} 22 |
    {{ edit_form.edit_reason.errors }}
    23 | {% endif %} 24 | {{ edit_form.edit_reason.label_tag }} {{ edit_form.edit_reason }} 25 |
    26 |
    27 | {{ edit_form.show_similies }} {{ edit_form.show_similies.help_text }} 28 |
    29 |

    30 |
    31 |
    32 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/post/edit_denied.html: -------------------------------------------------------------------------------- 1 | {% extends "forum/base.html" %} 2 | 3 | {% block content %} 4 | {% include "forum/post/crumbs.html" %} 5 |
    6 |

    We are sorry, but you don't have permissions to edit to this post.

    7 |

    Return to thread.

    8 |
    9 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/post/latest.html: -------------------------------------------------------------------------------- 1 | {% for thread in threads %}
  • {{ thread.subject }}
  • {% endfor %} -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/post/list_posts.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/forum/templates/forum/post/list_posts.html -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/post/posted.html: -------------------------------------------------------------------------------- 1 | {% extends "forum/base.html" %} 2 | 3 | {% block content %} 4 | {% include "forum/post/crumbs.html" %} 5 |

    6 | {% if post.is_spam %} 7 | Your post was made, but was flaged as spam. It will have to be reviwed by an admin before being made public. Return to Thread 8 | {% elif not post.is_public %} 9 | Your post was made, but will not be public till it has been view by an administrator. Return to Thread 10 | {% else %} 11 | Thank you for posting at our forums! You will be directed back to your post in {{ forums.post_redirect_delay }} second{{ forums.post_redirect_delay|pluralize }}. View Your Post 12 | {% endif %} 13 |

    14 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/post/report.html: -------------------------------------------------------------------------------- 1 | {% extends "forum/base.html" %} 2 | 3 | {% block content %} 4 | {% include "forum/post/crumbs.html" %} 5 |

    Report Post

    6 |
    7 | {% csrf_token %} 8 |
    9 | {{ report_form.as_p }} 10 |
    11 |

    12 |
    13 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/profile.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    Number of Posts{{ forum_profile.num_posts }}
    Number of Topics{{ forum_profile.num_threads }}
    -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/profile_subscriptions.html: -------------------------------------------------------------------------------- 1 |
    2 | Subscriptions 3 |

    Edit your Topic Subscriptions

    4 |
    -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/subscriptions.html: -------------------------------------------------------------------------------- 1 | 2 | {% if not subscriptions %} 3 |

    You do not have any subscriptions.

    4 | {% else %} 5 |

    6 | Here is a list of your subscriptions. Check the boxes for those that you would like to unsubscribe from. 7 |

    8 | 9 | {% for thread in subscriptions %} 10 | 11 | 12 | 13 | 14 | 15 | {% endfor %} 16 |
    {{ thread.subject }}{{ thread.posted }}
    17 | {% endif %} 18 | -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/thread/access.html: -------------------------------------------------------------------------------- 1 | {% extends "forum/base.html" %} 2 | 3 | {% block content %} 4 | {% include "forum/thread/crumbs.html" %} 5 |
    6 |

    You need to login first.

    7 |

    Login or Register.

    8 |
    9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/thread/actions.html: -------------------------------------------------------------------------------- 1 | {% if actions %} 2 |
    3 | {% for action in actions %} 4 | {% if not forloop.first %} • {% endif %} 5 | {{ action.name }} 6 | {% endfor %} 7 |
    8 | {% endif %} 9 | -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/thread/closed.html: -------------------------------------------------------------------------------- 1 | {% extends "forum/base.html" %} 2 | 3 | {% block content %} 4 | {% include "forum/thread/crumbs.html" %} 5 |

    6 | We are sorry, but this thread has been closed, and you can no longer reply to it. Return to thread. 7 |

    8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/thread/crumbs.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/thread/denied.html: -------------------------------------------------------------------------------- 1 | {% extends "forum/base.html" %} 2 | 3 | {% block content %} 4 | {% include "forum/thread/crumbs.html" %} 5 |
    6 | {% if anonymous %} 7 |

    We are sorry, but you don't have permissions to reply to this thread. 8 | Please Login 9 | or Register and try again.

    10 |

    Return to thread.

    11 | {% else %} 12 |

    We are sorry, but you don't have permissions to reply to this thread.

    13 |

    Return to thread.

    14 | {% endif %} 15 |
    16 | {% endblock %} 17 | -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/thread/list.html: -------------------------------------------------------------------------------- 1 | {% extends "forum/base.html" %} 2 | {% load show_pagination %} 3 | 4 | {% block content %} 5 | 9 |
    10 | {% simple_pagination threads pages %} 11 |
    12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | {% for thread in threads %} 23 | 24 | 29 | 30 | 31 | 32 | 33 | {% endfor %} 34 | 35 |
    TopicRepliesViewsLast post
    25 | {% if thread.sticky %}Sticky: {% endif %} 26 | {% if thread.closed %}Closed: {% endif %} 27 | {{ thread.subject }} by {{ thread.author_name }} 28 | {{ thread.num_posts|add:-1 }}{{ thread.num_views }}{{ thread.last_post.posted }} by {{ thread.last_post.author_name }}
    36 |
    37 | {% simple_pagination threads pages %} 38 |
    39 | {% endblock %} 40 | -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/thread/new_denied.html: -------------------------------------------------------------------------------- 1 | {% extends "forum/base.html" %} 2 | 3 | {% block content %} 4 | {% include "forum/thread/crumbs.html" %} 5 |
    6 | {% if anonymous %} 7 |

    We are sorry, but you don't have permissions to post a new thread. 8 | Please Login 9 | or Register and try again.

    10 |

    Return to thread.

    11 | {% else %} 12 |

    We are sorry, but you don't have permissions to post a new thread.

    13 |

    Return to thread.

    14 | {% endif %} 15 |
    16 | {% endblock %} 17 | -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/thread/subscribed.html: -------------------------------------------------------------------------------- 1 | {% extends "forum/base.html" %} 2 | 3 | {% block content %} 4 | {% include "forum/thread/crumbs.html" %} 5 |
    6 |

    You have been subscribed to the thread "{{ thread.subject }}".

    7 |

    Return to thread.

    8 |
    9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /djangopress/forum/templates/forum/thread/unsubscribed.html: -------------------------------------------------------------------------------- 1 | {% extends "forum/base.html" %} 2 | 3 | {% block content %} 4 | {% include "forum/thread/crumbs.html" %} 5 |
    6 |

    You have been unsubscribed from the thread "{{ thread.subject }}".

    7 |

    Return to thread.

    8 |
    9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /djangopress/forum/templates/search/indexes/forum/post_text.txt: -------------------------------------------------------------------------------- 1 | {% load forum_tags %} 2 | 3 | {{ object.thread.subject }} 4 | 5 | {{ object.author_name }} 6 | {% format_post object %} -------------------------------------------------------------------------------- /djangopress/forum/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/forum/templatetags/__init__.py -------------------------------------------------------------------------------- /djangopress/forum/tests.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file demonstrates two different styles of tests (one doctest and one 3 | unittest). These will both pass when you run "manage.py test". 4 | 5 | Replace these with more appropriate tests for your application. 6 | """ 7 | 8 | from django.test import TestCase 9 | 10 | class SimpleTest(TestCase): 11 | def test_basic_addition(self): 12 | """ 13 | Tests that 1 + 1 always equals 2. 14 | """ 15 | self.failUnlessEqual(1 + 1, 2) 16 | 17 | __test__ = {"doctest": """ 18 | Another way to test that 1 + 1 is equal to 2. 19 | 20 | >>> 1 + 1 == 2 21 | True 22 | """} 23 | 24 | -------------------------------------------------------------------------------- /djangopress/gallery/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/gallery/__init__.py -------------------------------------------------------------------------------- /djangopress/gallery/image_urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | from .views import crop, resize 3 | 4 | """ 5 | These can help with the serving of images as a dynamic size. 6 | """ 7 | 8 | urlpatterns = [ 9 | url(r'^crop/(?P\d+)x(?P\d+)/(?P.+)', crop, 10 | name='gallery-crop'), 11 | url(r'^resize/(?P\d+)x(?P\d+)/(?P.+)', resize, 12 | name='gallery-resize'), 13 | url(r'^resize/(?P\d+)w/(?P.+)', resize, name='gallery-resize'), 14 | url(r'^resize/(?P\d+)h/(?P.+)', resize, name='gallery-resize'), 15 | ] -------------------------------------------------------------------------------- /djangopress/gallery/menus.py: -------------------------------------------------------------------------------- 1 | from djangopress.menus.menu import register 2 | from django.template import Template, RequestContext 3 | from .models import GallerySection 4 | 5 | class GalleryRender(object): 6 | 7 | _menu = Template(""" 8 | 9 | {% for gallery in galleries %} 10 |
  • {{ gallery.title }}
  • 11 | {% endfor %} 12 | """) 13 | 14 | _item = Template(""" 15 |
  • 16 | {{ item.label }} 17 | 23 |
  • """) 24 | 25 | def render_menu(self, context, tree, menu=None, renderer=None): 26 | galleries = GallerySection.objects.filter( 27 | listed=True).order_by("position") 28 | return self._menu.render(RequestContext(context.get("request"), {"tree": tree, "galleries": galleries})) 29 | 30 | 31 | def render_item(self, context, item, sub_menu): 32 | galleries = GallerySection.objects.filter( 33 | listed=True).order_by("position") 34 | return self._item.render(RequestContext(context.get("request"), {"item": item, "galleries": galleries})) 35 | 36 | 37 | 38 | register('gallery', GalleryRender()) -------------------------------------------------------------------------------- /djangopress/gallery/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ] 11 | 12 | operations = [ 13 | migrations.CreateModel( 14 | name='GallerySection', 15 | fields=[ 16 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 17 | ('title', models.CharField(max_length=100)), 18 | ('position', models.IntegerField()), 19 | ('slug', models.SlugField()), 20 | ('description', models.TextField(blank=True)), 21 | ], 22 | ), 23 | migrations.CreateModel( 24 | name='Image', 25 | fields=[ 26 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 27 | ('image', models.ImageField(height_field=b'height', width_field=b'width', upload_to=b'images/gallery/')), 28 | ('thumbnail', models.ImageField(upload_to=b'images/gallery/thumbs/', editable=False)), 29 | ('description', models.TextField()), 30 | ('width', models.IntegerField(editable=False)), 31 | ('height', models.IntegerField(editable=False)), 32 | ('gallery', models.ForeignKey(to='gallery.GallerySection', on_delete=models.CASCADE)), 33 | ], 34 | ), 35 | ] 36 | -------------------------------------------------------------------------------- /djangopress/gallery/migrations/0002_auto_20150801_0911.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('gallery', '0001_initial'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='image', 16 | name='scaled', 17 | field=models.ImageField(upload_to=b'images/gallery/scaled/', null=True, editable=False, blank=True), 18 | ), 19 | migrations.AlterField( 20 | model_name='image', 21 | name='description', 22 | field=models.TextField(null=True, blank=True), 23 | ), 24 | migrations.AlterField( 25 | model_name='image', 26 | name='gallery', 27 | field=models.ForeignKey(blank=True, to='gallery.GallerySection', null=True, on_delete=models.CASCADE), 28 | ), 29 | ] 30 | -------------------------------------------------------------------------------- /djangopress/gallery/migrations/0003_gallerysection_listed.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('gallery', '0002_auto_20150801_0911'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='gallerysection', 16 | name='listed', 17 | field=models.BooleanField(default=True), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /djangopress/gallery/migrations/0004_auto_20150803_0505.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | import datetime 6 | from django.utils.timezone import utc 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ('gallery', '0003_gallerysection_listed'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AddField( 17 | model_name='image', 18 | name='date', 19 | field=models.DateTimeField(default=datetime.datetime(2015, 8, 3, 5, 5, 29, 910904), auto_now_add=True), 20 | preserve_default=False, 21 | ), 22 | migrations.AlterField( 23 | model_name='image', 24 | name='image', 25 | field=models.ImageField(height_field=b'height', width_field=b'width', upload_to=b'images/gallery/%y/%m/'), 26 | ), 27 | migrations.AlterField( 28 | model_name='image', 29 | name='scaled', 30 | field=models.ImageField(upload_to=b'images/gallery/scaled/%y/%m/', null=True, editable=False, blank=True), 31 | ), 32 | migrations.AlterField( 33 | model_name='image', 34 | name='thumbnail', 35 | field=models.ImageField(upload_to=b'images/gallery/thumbs/%y/%m/', editable=False), 36 | ), 37 | ] 38 | -------------------------------------------------------------------------------- /djangopress/gallery/migrations/0005_auto_20150805_0826.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('gallery', '0004_auto_20150803_0505'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='image', 16 | name='thumbnail', 17 | field=models.ImageField(upload_to=b'images/gallery/thumbs/%y/%m/', null=True, editable=False, blank=True), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /djangopress/gallery/migrations/0006_image_position.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('gallery', '0005_auto_20150805_0826'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='image', 16 | name='position', 17 | field=models.IntegerField(default=0), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /djangopress/gallery/migrations/0007_auto_20150829_0924.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('gallery', '0006_image_position'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='gallerysection', 16 | name='position', 17 | field=models.IntegerField(default=0), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /djangopress/gallery/migrations/0008_auto_20150921_0602.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('gallery', '0007_auto_20150829_0924'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='gallerysection', 16 | name='slug', 17 | field=models.SlugField(unique=True), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /djangopress/gallery/migrations/0009_auto_20170710_0953.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.3 on 2017-07-10 09:54 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('gallery', '0008_auto_20150921_0602'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='image', 17 | name='image', 18 | field=models.ImageField(height_field='height', upload_to='images/gallery/%y/%m/', width_field='width'), 19 | ), 20 | migrations.AlterField( 21 | model_name='image', 22 | name='scaled', 23 | field=models.ImageField(blank=True, editable=False, null=True, upload_to='images/gallery/scaled/%y/%m/'), 24 | ), 25 | migrations.AlterField( 26 | model_name='image', 27 | name='thumbnail', 28 | field=models.ImageField(blank=True, editable=False, null=True, upload_to='images/gallery/thumbs/%y/%m/'), 29 | ), 30 | ] 31 | -------------------------------------------------------------------------------- /djangopress/gallery/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/gallery/migrations/__init__.py -------------------------------------------------------------------------------- /djangopress/gallery/sitemaps.py: -------------------------------------------------------------------------------- 1 | from django.contrib.sitemaps import Sitemap 2 | from .models import GallerySection 3 | from djangopress.core.sitemap import register 4 | 5 | class GallerySitemap(Sitemap): 6 | lastmod = None 7 | 8 | def items(self): 9 | return GallerySection.objects.all() 10 | 11 | register('gallery-section', GallerySitemap) -------------------------------------------------------------------------------- /djangopress/gallery/templates/gallery/admin_change_gallery.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/base_site.html" %} 2 | 3 | {% block content %} 4 | 5 |

    Select gallery to move to:

    6 | 7 |
    8 | {% csrf_token %} 9 | {{ gallery_form }} 10 | 11 |

    The tag will be applied to:

    12 | 13 |
      {{ images|unordered_list }}
    14 | 15 | 16 | 17 |
    18 | 19 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/gallery/templates/gallery/admin_gallery_as_html.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/base_site.html" %} 2 | {% load gallery_tags %} 3 | 4 | {% block content %} 5 | 6 |
    7 | {% csrf_token %} 8 | {{ gallery_form }} 9 | 10 | 11 | 12 |
    13 |

    14 | Back to Gallery Index 15 |

    16 | {% for gallery in galleries %} 17 |

    {{ gallery.title }}

    18 | 19 | {% endfor %} 20 |

    21 | Back to Gallery Index 22 |

    23 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/gallery/templates/gallery/admin_images_as_html.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/base_site.html" %} 2 | {% load gallery_tags %} 3 | 4 | {% block content %} 5 | 6 |
    7 | {% csrf_token %} 8 | {{ gallery_form }} 9 | 10 | 11 | 12 |
    13 |

    14 | Back to Image Index 15 |

    16 | 17 | 18 | 19 |

    20 | Back to Image Index 21 |

    22 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/gallery/templates/gallery/gallery.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load gallery_tags %} 3 | 4 | {% block page_title %} 5 | {{ gallery.title }} 6 | {% endblock %} 7 | 8 | {% block content %} 9 |

    {{ gallery.title }}

    10 | {{ gallery.description|safe }} 11 | 20 | {% endblock %} 21 | -------------------------------------------------------------------------------- /djangopress/gallery/templates/gallery/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load gallery_tags %} 3 | 4 | {% block page_title %} 5 | Photo Gallery 6 | {% endblock %} 7 | 8 | {% block content-title %} 9 | Photo Gallery 10 | {% endblock %} 11 | 12 | {% block content %} 13 | {% for gallery, images in galleries %} 14 | 27 | {% endfor %} 28 | {% endblock %} 29 | -------------------------------------------------------------------------------- /djangopress/gallery/templates/gallery/slider.html: -------------------------------------------------------------------------------- 1 | {% load gallery_tags %} 2 | 3 |
    4 |
     
    5 |
    6 | {% for image in images %} 7 | {{ image.description|striptags }} 8 | {% endfor %} 9 |
    10 | {% for image in images %} 11 | {% if image.description %} 12 |
    13 |

    {{ image.description|safe }}

    14 |
    15 | {% endif %} 16 | {% endfor %} 17 |
    18 | -------------------------------------------------------------------------------- /djangopress/gallery/templates/gallery/tag.html: -------------------------------------------------------------------------------- 1 | {% load gallery_tags %} 2 | 3 | {% if show_title %} 4 |

    {{ gallery.title|safe }}

    5 | {% endif %} 6 | {% if show_description %} 7 | {{ gallery.description|safe }} 8 | {% endif %} 9 | -------------------------------------------------------------------------------- /djangopress/gallery/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/gallery/templatetags/__init__.py -------------------------------------------------------------------------------- /djangopress/gallery/templatetags/gallery_tags.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | from django.utils.safestring import mark_safe 3 | from ..models import GALLERY_SETTINGS 4 | 5 | register = template.Library() 6 | 7 | @register.simple_tag(takes_context=True) 8 | def gallery_as_html(context, gallery): 9 | return mark_safe(gallery.as_html(thumber=context.get('thumber'))) 10 | 11 | @register.simple_tag(takes_context=True) 12 | def gallery_thumbnail(context, image): 13 | thumber = context.get('thumber') 14 | sizes = GALLERY_SETTINGS.get("sizes").get("thumb") 15 | t = template.Template("""{{ image.description|striptags }}""") 16 | if thumber: 17 | context.update({ 18 | "width": thumber.width, 19 | "height": thumber.height, 20 | "thumbnail": thumber.thumb(image), 21 | "image": image 22 | }) 23 | else: 24 | context.update({ 25 | "width": sizes.get('width'), 26 | "height": sizes.get('height'), 27 | "thumbnail": image.thumbnail, 28 | "image": image 29 | }) 30 | return mark_safe(t.render(context).strip()) -------------------------------------------------------------------------------- /djangopress/gallery/tests.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file demonstrates writing tests using the unittest module. These will pass 3 | when you run "manage.py test". 4 | 5 | Replace this with more appropriate tests for your application. 6 | """ 7 | 8 | from django.test import TestCase 9 | 10 | 11 | class SimpleTest(TestCase): 12 | def test_basic_addition(self): 13 | """ 14 | Tests that 1 + 1 always equals 2. 15 | """ 16 | self.assertEqual(1 + 1, 2) 17 | -------------------------------------------------------------------------------- /djangopress/gallery/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | from .views import index, gallery, upload 3 | 4 | urlpatterns = [ 5 | url(r'^$', index, name='gallery-index'), 6 | url(r'^upload/$', upload, name='gallery-upload'), 7 | url(r'^(?P.+)/$', gallery, name='gallery-gallery'), 8 | ] 9 | -------------------------------------------------------------------------------- /djangopress/iptools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/iptools/__init__.py -------------------------------------------------------------------------------- /djangopress/iptools/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /djangopress/iptools/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/iptools/migrations/__init__.py -------------------------------------------------------------------------------- /djangopress/iptools/models.py: -------------------------------------------------------------------------------- 1 | import os 2 | import geoip2.database 3 | from django.conf import settings 4 | 5 | 6 | DEFAULT_DATABASE_FILE = os.path.join(settings.BASE_DIR, '..', 'db', 'GeoLite2-City.mmdb') 7 | DATABASE_FILE = getattr(settings, "GEOLITE2_DATABASE_FILE", DEFAULT_DATABASE_FILE) 8 | 9 | # this expensive so putting it here is how we make it run once at startup 10 | reader = geoip2.database.Reader(DATABASE_FILE) -------------------------------------------------------------------------------- /djangopress/iptools/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/iptools/templatetags/__init__.py -------------------------------------------------------------------------------- /djangopress/iptools/templatetags/iptools_tags.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | from django.utils.safestring import mark_safe 3 | from djangopress.iptools.views import get_ip_country_flag 4 | register = template.Library() 5 | 6 | @register.simple_tag 7 | def ip_country_flag(ip_address): 8 | if not ip_address: 9 | return '' 10 | flag, iso_code = get_ip_country_flag(ip_address) 11 | if flag: 12 | return mark_safe('%s' % (flag, iso_code)) 13 | return '' -------------------------------------------------------------------------------- /djangopress/iptools/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /djangopress/iptools/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | from djangopress.iptools import views 3 | 4 | urlpatterns = [ 5 | url(r'^$', views.index, name='iptools-index'), 6 | ] 7 | -------------------------------------------------------------------------------- /djangopress/menus/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/menus/__init__.py -------------------------------------------------------------------------------- /djangopress/menus/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from djangopress.menus.models import Menu, MenuItem 3 | 4 | class MenuAdmin(admin.ModelAdmin): 5 | list_display = ['name'] 6 | admin.site.register(Menu, MenuAdmin) 7 | 8 | class MenuItemAdmin(admin.ModelAdmin): 9 | list_display = ['label', 'link', 'menu', 'parent', 'index'] 10 | list_editable = ('index', ) 11 | ordering = ('menu', 'parent', 'index') 12 | 13 | admin.site.register(MenuItem, MenuItemAdmin) 14 | -------------------------------------------------------------------------------- /djangopress/menus/menu.py: -------------------------------------------------------------------------------- 1 | class MenusRegister(object): 2 | 3 | def __init__(self): 4 | self._renderer = {} 5 | 6 | def __call__(self, name, cls, position=0): 7 | self._renderer[name] = cls 8 | 9 | def list_all(self): 10 | return self._renderer 11 | 12 | def get_renderer(self, name): 13 | return self._renderer.get(name) 14 | 15 | register = MenusRegister() 16 | 17 | def autodiscover(): 18 | "based on the admin site autodiscover see that for more info" 19 | import copy 20 | from django.conf import settings 21 | from importlib import import_module 22 | from django.utils.module_loading import module_has_submodule 23 | 24 | for app in settings.INSTALLED_APPS: 25 | mod = import_module(app) 26 | try: 27 | before_import_registry = copy.copy(register._renderer) 28 | import_module('%s.menus' % app) 29 | except: 30 | register._renderer = before_import_registry 31 | if module_has_submodule(mod, 'menus'): 32 | raise 33 | -------------------------------------------------------------------------------- /djangopress/menus/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ] 11 | 12 | operations = [ 13 | migrations.CreateModel( 14 | name='Menu', 15 | fields=[ 16 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 17 | ('name', models.CharField(unique=True, max_length=100)), 18 | ('class_tag', models.CharField(max_length=100, null=True, blank=True)), 19 | ('renderer', models.CharField(default=b'default', max_length=100)), 20 | ], 21 | options={ 22 | }, 23 | bases=(models.Model,), 24 | ), 25 | migrations.CreateModel( 26 | name='MenuItem', 27 | fields=[ 28 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 29 | ('label', models.CharField(max_length=100)), 30 | ('link', models.CharField(max_length=255, null=True, blank=True)), 31 | ('index', models.IntegerField(default=0)), 32 | ('id_tag', models.CharField(max_length=100, null=True, blank=True)), 33 | ('class_tag', models.CharField(max_length=100, null=True, blank=True)), 34 | ('renderer', models.CharField(default=b'default', max_length=100)), 35 | ('menu', models.ForeignKey(to='menus.Menu', on_delete=models.CASCADE)), 36 | ('parent', models.ForeignKey(blank=True, to='menus.MenuItem', null=True, on_delete=models.CASCADE)), 37 | ], 38 | options={ 39 | }, 40 | bases=(models.Model,), 41 | ), 42 | ] 43 | -------------------------------------------------------------------------------- /djangopress/menus/migrations/0002_auto_20170710_0953.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.3 on 2017-07-10 09:54 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('menus', '0001_initial'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='menu', 17 | name='renderer', 18 | field=models.CharField(default='default', max_length=100), 19 | ), 20 | migrations.AlterField( 21 | model_name='menuitem', 22 | name='renderer', 23 | field=models.CharField(default='default', max_length=100), 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /djangopress/menus/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/menus/migrations/__init__.py -------------------------------------------------------------------------------- /djangopress/menus/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from djangopress.menus.menu import register as menu_register 3 | 4 | class Menu(models.Model): 5 | name = models.CharField(max_length=100, unique=True) 6 | class_tag = models.CharField(max_length=100, null=True, blank=True) 7 | renderer = models.CharField(max_length=100, default="default") 8 | 9 | def __str__(self): 10 | return self.name 11 | 12 | class MenuItem(models.Model): 13 | label = models.CharField(max_length=100) 14 | link = models.CharField(max_length=255, null=True, blank=True) 15 | 16 | menu = models.ForeignKey(Menu, on_delete=models.CASCADE) 17 | parent = models.ForeignKey('MenuItem', null=True, blank=True, on_delete=models.CASCADE) 18 | 19 | index = models.IntegerField(default=0) 20 | 21 | id_tag = models.CharField(max_length=100, null=True, blank=True) 22 | class_tag = models.CharField(max_length=100, null=True, blank=True) 23 | renderer = models.CharField(max_length=100, default="default", choices=list(menu_register.list_all().items())) 24 | 25 | def __str__(self): 26 | return "%s (#%s)" % (self.label, self.pk) 27 | 28 | from djangopress.menus.menu import autodiscover 29 | 30 | autodiscover() -------------------------------------------------------------------------------- /djangopress/menus/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/menus/templatetags/__init__.py -------------------------------------------------------------------------------- /djangopress/menus/templatetags/display_menu.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | from djangopress.menus.menu import register as menu_register 3 | from djangopress.menus.models import Menu, MenuItem 4 | from django.conf import settings 5 | 6 | register = template.Library() 7 | 8 | @register.simple_tag(takes_context=True) 9 | def display_menu(context, menu_name, renderer=None): 10 | try: 11 | menu = Menu.objects.get(name=menu_name) 12 | except: 13 | return "" 14 | menu_items = MenuItem.objects.filter(menu=menu).select_related('parent') 15 | nodes = dict((item, {}) for item in menu_items) 16 | for item in menu_items: 17 | if item.parent is not None: 18 | nodes[item.parent][item] = nodes[item] 19 | tree = dict((key, value) for key, value in nodes.items() if key.parent is None) 20 | try: 21 | return menu_register.get_renderer(renderer if renderer else menu.renderer).render_menu(context, tree, menu, renderer) 22 | except Exception as e: 23 | if settings.DEBUG: 24 | raise e 25 | return "" 26 | 27 | @register.simple_tag(takes_context=True) 28 | def display_menu_item(context, item, submenu, renderer=None): 29 | return menu_register.get_renderer(renderer if renderer else item.renderer).render_item(context, item, submenu) 30 | 31 | @register.simple_tag(takes_context=True) 32 | def display_submenu(context, item, submenu, renderer=None): 33 | return menu_register.get_renderer(renderer if renderer else item.renderer).render_menu(context, submenu) -------------------------------------------------------------------------------- /djangopress/menus/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /djangopress/menus/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | # Create your views here. 4 | -------------------------------------------------------------------------------- /djangopress/pages/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/pages/__init__.py -------------------------------------------------------------------------------- /djangopress/pages/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from djangopress.pages.models import Page, PageBlock 3 | 4 | 5 | class NewBlockForm(forms.ModelForm): 6 | class Meta: 7 | model = PageBlock 8 | fields = ('render',) 9 | 10 | class TextForm(forms.ModelForm): 11 | 12 | class Meta: 13 | fields = ("render", "data") 14 | model = PageBlock 15 | 16 | class PageForm(forms.ModelForm): 17 | fieldsets = ( 18 | ("Page Details", ('slug', 'title', 'override_location', 'parent')), 19 | ("Display Settings", ('status', 'visibility', 'login_required')), 20 | ("SEO Options", ('meta_page_title', 'meta_keywords', 'meta_description')) 21 | ) 22 | class Meta: 23 | model = Page 24 | fields = ('slug', 'title', 'status', 'visibility', 'login_required', 25 | 'override_location', 'parent', 26 | 'meta_page_title', 'meta_keywords', 'meta_description') 27 | widgets = { 28 | 'meta_page_title': forms.TextInput(), 29 | 'meta_keywords': forms.Textarea(attrs={"rows": 3, "cols": 40} ), 30 | 'meta_description': forms.Textarea(attrs={"rows": 3, "cols": 40} ) 31 | } -------------------------------------------------------------------------------- /djangopress/pages/middleware.py: -------------------------------------------------------------------------------- 1 | from djangopress.pages.views import show_page 2 | from django.http import Http404 3 | from django.conf import settings 4 | 5 | 6 | class PagesMiddleware(object): 7 | def process_response(self, request, response): 8 | if response.status_code != 404: 9 | return response # No need to check for a flatpage for non-404 responses. 10 | try: 11 | return show_page(request, request.path) 12 | # Return the original response if any errors happened. Because this 13 | # is a middleware, we can't assume the errors will be caught elsewhere. 14 | except Http404: 15 | return response 16 | except: 17 | if settings.DEBUG: 18 | raise 19 | return response 20 | -------------------------------------------------------------------------------- /djangopress/pages/migrations/0002_page_head_tags.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('pages', '0001_initial'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='page', 16 | name='head_tags', 17 | field=models.TextField(null=True, verbose_name=b'Extra tags to be added to the page header', blank=True), 18 | preserve_default=True, 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /djangopress/pages/migrations/0003_auto_20140907_0926.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('pages', '0002_page_head_tags'), 11 | ] 12 | 13 | operations = [ 14 | migrations.RemoveField( 15 | model_name='textblock', 16 | name='pageblock_ptr', 17 | ), 18 | migrations.RemoveField( 19 | model_name='page', 20 | name='blocks', 21 | ), 22 | migrations.DeleteModel( 23 | name='TextBlock', 24 | ), 25 | migrations.RemoveField( 26 | model_name='pageblock', 27 | name='class_name', 28 | ), 29 | migrations.AddField( 30 | model_name='pageblock', 31 | name='data', 32 | field=models.TextField(default='', verbose_name=b'Content', blank=True), 33 | preserve_default=False, 34 | ), 35 | migrations.AddField( 36 | model_name='pageblock', 37 | name='page', 38 | field=models.ForeignKey(blank=True, to='pages.Page', null=True, on_delete=models.CASCADE), 39 | preserve_default=True, 40 | ), 41 | migrations.AddField( 42 | model_name='pageblock', 43 | name='render', 44 | field=models.CharField(default='html', max_length=30, choices=[(b'magic_html', b'Magic HTML'), (b'bbcode', b'BBcode'), (b'sanitized_html', b'Sanitized HTML'), (b'plain_text', b'Plain Text'), (b'html', b'HTML'), (b'template', b'Django Template')]), 45 | preserve_default=False, 46 | ), 47 | ] 48 | -------------------------------------------------------------------------------- /djangopress/pages/migrations/0004_auto_20140912_0112.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('pages', '0003_auto_20140907_0926'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='pageblock', 16 | name='block_name', 17 | field=models.CharField(max_length=50, db_index=True), 18 | ), 19 | migrations.AlterField( 20 | model_name='pageblock', 21 | name='page', 22 | field=models.ForeignKey(related_name=b'blocks', blank=True, to='pages.Page', null=True, on_delete=models.CASCADE), 23 | ), 24 | ] 25 | -------------------------------------------------------------------------------- /djangopress/pages/migrations/0005_auto_20141001_1845.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('pages', '0004_auto_20140912_0112'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='page', 16 | name='location', 17 | field=models.CharField(max_length=200, unique=True, null=True, editable=False, blank=True), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /djangopress/pages/migrations/0006_auto_20141005_1948.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('pages', '0005_auto_20141001_1845'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='pageblock', 16 | name='render', 17 | field=models.CharField(max_length=30, choices=[(b'magic_html', b'Magic HTML'), (b'markdown', b'Markdown'), (b'bbcode', b'BBcode'), (b'sanitized_html', b'Sanitized HTML'), (b'plain_text', b'Plain Text'), (b'html', b'HTML'), (b'template', b'Django Template'), (b'restructuredtext', b'reStructuredText')]), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /djangopress/pages/migrations/0007_auto_20150426_1817.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('pages', '0006_auto_20141005_1948'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='pageblock', 16 | name='render', 17 | field=models.CharField(max_length=30, choices=[(b'extended_html', b'Extended HTML'), (b'magic_html', b'Magic HTML'), (b'markdown', b'Markdown'), (b'bbcode', b'BBcode'), (b'sanitized_html', b'Sanitized HTML'), (b'plain_text', b'Plain Text'), (b'html', b'HTML'), (b'template', b'Django Template'), (b'restructuredtext', b'reStructuredText')]), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /djangopress/pages/migrations/0009_page_image.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | import djangopress.pages.models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('pages', '0008_auto_20150730_0004'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='page', 17 | name='image', 18 | field=models.ImageField(null=True, upload_to=djangopress.pages.models.page_file_path, blank=True), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /djangopress/pages/migrations/0010_auto_20150803_0515.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('pages', '0009_page_image'), 11 | ] 12 | 13 | operations = [ 14 | migrations.RemoveField( 15 | model_name='pagefile', 16 | name='page', 17 | ), 18 | migrations.DeleteModel( 19 | name='PageFile', 20 | ), 21 | ] 22 | -------------------------------------------------------------------------------- /djangopress/pages/migrations/0012_auto_20170710_0959.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.3 on 2017-07-10 09:59 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('pages', '0011_auto_20170710_0953'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='pageblock', 17 | name='render', 18 | field=models.CharField(choices=[('magic_html', 'Magic HTML'), ('sanitized_html', 'Sanitized HTML'), ('extended_html', 'Extended HTML'), ('template', 'Django Template'), ('html', 'HTML'), ('plain_text', 'Plain Text'), ('bbcode', 'BBcode'), ('markdown', 'Markdown')], default='extended_html', max_length=30), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /djangopress/pages/migrations/0013_auto_20170714_0541.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.3 on 2017-07-14 05:41 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('pages', '0012_auto_20170710_0959'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='pageblock', 17 | name='render', 18 | field=models.CharField(choices=[('plain_text', 'Plain Text'), ('magic_html', 'Magic HTML'), ('markdown', 'Markdown'), ('html', 'HTML'), ('extended_html', 'Extended HTML'), ('sanitized_html', 'Sanitized HTML'), ('bbcode', 'BBcode'), ('template', 'Django Template')], default='extended_html', max_length=30), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /djangopress/pages/migrations/0014_auto_20170724_1238.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.3 on 2017-07-24 12:38 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('pages', '0013_auto_20170714_0541'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='pageblock', 17 | name='render', 18 | field=models.CharField(choices=[('markdown', 'Markdown'), ('template', 'Django Template'), ('plain_text', 'Plain Text'), ('sanitized_html', 'Sanitized HTML'), ('bbcode', 'BBcode'), ('html', 'HTML'), ('magic_html', 'Magic HTML'), ('extended_html', 'Extended HTML')], default='extended_html', max_length=30), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /djangopress/pages/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/pages/migrations/__init__.py -------------------------------------------------------------------------------- /djangopress/pages/render.py: -------------------------------------------------------------------------------- 1 | from djangopress.core.format import library 2 | 3 | class RenderRegister(object): 4 | 5 | def __init__(self): 6 | self._func = {} 7 | self._choices = {} 8 | 9 | def __call__(self, name, func, verbose_name): 10 | self._func[name] = func 11 | self._choices[name] = verbose_name 12 | 13 | def choices(self): 14 | return list(self._choices.items()) 15 | 16 | def render(self, block, name, data, context): 17 | func = self._func.get(name) 18 | if func: 19 | return func(block, data, context) 20 | return '' 21 | 22 | register = RenderRegister() 23 | 24 | def make_render(name): 25 | return lambda block, data, context: library.Library.format(name, data, False, context=context) 26 | 27 | for name, verbose_name in library.Library.choices(False): 28 | register(name, make_render(name), verbose_name) -------------------------------------------------------------------------------- /djangopress/pages/search_indexes.py: -------------------------------------------------------------------------------- 1 | from haystack import indexes 2 | from djangopress.pages.models import Page 3 | 4 | class PagesIndex(indexes.SearchIndex, indexes.Indexable): 5 | text = indexes.CharField(document=True, use_template=True) 6 | author = indexes.CharField(model_attr='author') 7 | pub_date = indexes.DateTimeField(model_attr='edited') 8 | title = indexes.CharField(model_attr='title', boost=1.5) 9 | 10 | def get_model(self): 11 | return Page 12 | 13 | def index_queryset(self, using=None): 14 | """Used when the entire index for model is updated.""" 15 | return self.get_model().objects.filter(status="PB", visibility="VI") 16 | 17 | def prepare(self, obj): 18 | data = super(PagesIndex, self).prepare(obj) 19 | data['boost'] = 1.5 20 | return data 21 | -------------------------------------------------------------------------------- /djangopress/pages/sitemaps.py: -------------------------------------------------------------------------------- 1 | from django.contrib.sitemaps import Sitemap 2 | from djangopress.pages.models import Page 3 | from djangopress.core.sitemap import register 4 | from django.conf import settings 5 | 6 | class PageSitemap(Sitemap): 7 | 8 | def items(self): 9 | return Page.objects.filter(sites__id__exact=settings.SITE_ID, 10 | visibility="VI", status="PB") 11 | 12 | def lastmod(self, obj): 13 | return obj.edited 14 | 15 | register('page', PageSitemap) -------------------------------------------------------------------------------- /djangopress/pages/static/pages/images/accept.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/pages/static/pages/images/accept.png -------------------------------------------------------------------------------- /djangopress/pages/static/pages/images/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/pages/static/pages/images/error.png -------------------------------------------------------------------------------- /djangopress/pages/static/pages/images/exclamation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/pages/static/pages/images/exclamation.png -------------------------------------------------------------------------------- /djangopress/pages/static/pages/images/information.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/pages/static/pages/images/information.png -------------------------------------------------------------------------------- /djangopress/pages/templates/pages/editor/block.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block page_title %} 4 | {% if page.meta_page_title %} 5 | {{ page.meta_page_title }} 6 | {% else %} 7 | {{ page.title }} 8 | {% endif %} 9 | {% endblock %} 10 | 11 | {% block content %} 12 | {% include "pages/editor/block-form.html" %} 13 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/pages/templates/pages/editor/details-form.html: -------------------------------------------------------------------------------- 1 | {% load field_form %} 2 | 3 |
    4 | {% field_form form %} 5 |
    6 | Submit 7 | {% csrf_token %} 8 | 9 |
    10 |
    -------------------------------------------------------------------------------- /djangopress/pages/templates/pages/editor/details.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block page_title %} 4 | {% if page.meta_page_title %} 5 | {{ page.meta_page_title }} 6 | {% else %} 7 | {{ page.title }} 8 | {% endif %} 9 | {% endblock %} 10 | 11 | {% block content %} 12 | {% include "pages/editor/details-form.html" %} 13 | {% endblock %} -------------------------------------------------------------------------------- /djangopress/pages/templates/pages/editor/page_block.html: -------------------------------------------------------------------------------- 1 |
    2 | 9 |
    10 | {{ content|safe }} 11 |
    12 |
    13 |
    14 | -------------------------------------------------------------------------------- /djangopress/pages/templates/pages/js/edit-page.js: -------------------------------------------------------------------------------- 1 | var pageDetailsOpen = false; 2 | 3 | function editContentByIdent(event, ident, page) { 4 | return displayPane(event, {action : 'edit-block', page: page, identifier: ident}); 5 | } 6 | 7 | function editContentByName(event, name, page) { 8 | return displayPane(event, {action : 'edit-block', page: page, name: name}); 9 | } 10 | 11 | function editPage(event, page) { 12 | return displayPane(event, {action : 'edit-page', page: page}); 13 | } 14 | 15 | function displayPane(event, data) { 16 | event.preventDefault(); 17 | if(pageDetailsOpen) { 18 | $('#page-edit-pane').detach(); 19 | } 20 | $.ajax({ 21 | url: '{% url 'page-edit-ajax' %}', 22 | type: "GET", 23 | data: data, 24 | dataType: "html", 25 | success: function(msg){ 26 | $('body').append('
    ' + msg + '
    '); 27 | pageDetailsOpen = true; 28 | var height = $('#page-edit-pane').height(); 29 | $('html').css("minHeight", (height + 200) + "px"); 30 | document.getElementsByTagName("html")[0].scrollTop = 0; 31 | } 32 | } 33 | ) 34 | return true; 35 | } -------------------------------------------------------------------------------- /djangopress/pages/templates/search/indexes/pages/page_text.txt: -------------------------------------------------------------------------------- 1 | {{ object.title }} 2 | {% for block in object.blocks.all %} 3 | {{ block.content|striptags|safe }} 4 | {% endfor %} 5 | -------------------------------------------------------------------------------- /djangopress/pages/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/pages/templatetags/__init__.py -------------------------------------------------------------------------------- /djangopress/pages/tests.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file demonstrates two different styles of tests (one doctest and one 3 | unittest). These will both pass when you run "manage.py test". 4 | 5 | Replace these with more appropriate tests for your application. 6 | """ 7 | 8 | from django.test import TestCase 9 | 10 | class SimpleTest(TestCase): 11 | def test_basic_addition(self): 12 | """ 13 | Tests that 1 + 1 always equals 2. 14 | """ 15 | self.failUnlessEqual(1 + 1, 2) 16 | 17 | __test__ = {"doctest": """ 18 | Another way to test that 1 + 1 is equal to 2. 19 | 20 | >>> 1 + 1 == 2 21 | True 22 | """} 23 | 24 | -------------------------------------------------------------------------------- /djangopress/pages/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | from djangopress.pages import views 3 | 4 | urlpatterns = [ 5 | url(r'^edit/(?P\d+)/(?P[\w\-]+)/$', views.page_edit, name='page-edit'), 6 | url(r'^edit-ident/(?P\d+)/(?P[\w\-]+)/$', views.page_edit, name='page-edit-ident'), 7 | url(r'^edit/(?P\d+)/$', views.page_edit_details, name='page-edit-details'), 8 | url(r'^page-edit.js', views.page_edit_js, name='page-edit-js'), 9 | url(r'^edit/ajax/', views.page_edit_ajax, name='page-edit-ajax'), 10 | ] -------------------------------------------------------------------------------- /djangopress/search_sites.py: -------------------------------------------------------------------------------- 1 | import haystack 2 | haystack.autodiscover() -------------------------------------------------------------------------------- /djangopress/settings.py: -------------------------------------------------------------------------------- 1 | ACCOUNTS_USER_LIMITS = { 2 | "avatar": { 3 | "size": 50, 4 | "file_size": 1024*100, 5 | "max_upload_size": 200, 6 | }, 7 | "attachments": { 8 | "file_size": 1024*500, 9 | "total": 1024*1024*5, 10 | }, 11 | "signature": { 12 | "lines": 4, 13 | "length": 500, 14 | "images": True, 15 | "links": True, 16 | } 17 | } -------------------------------------------------------------------------------- /djangopress/settings_tinymce.py: -------------------------------------------------------------------------------- 1 | # if you want support for tinymce in the admin pages 2 | # add tinymce to the installed apps (after installing if needed) 3 | # and then import these settings, or copy and adjust as needed 4 | 5 | TINYMCE_DEFAULT_CONFIG = { 6 | 'relative_urls': False, 7 | 'plugins': "table code image link colorpicker textcolor wordcount", 8 | 'tools': "inserttable", 9 | 'toolbar': "undo redo | styleselect fontsizeselect fontselect | removeformat | bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image | forecolor backcolor", 10 | 'extended_valid_elements': 'script[language|type|src],events[template|start],#gallery[class|id|show_description|show_title|count|slider],#show_blog_latest[class|id|words|images|blog|count]' 11 | } 12 | TINYMCE_JS_URL = "/static/js/tinymce/tinymce.min.js" -------------------------------------------------------------------------------- /djangopress/setup.sh: -------------------------------------------------------------------------------- 1 | #python ../manage.py sqlclear blog links pages menus sites downloads forum auth donate ipn 2 | rm -f ../*.db 3 | echo "no" | python ../manage.py syncdb 4 | python ../manage.py loaddata ../fixtures/*.json 5 | 6 | -------------------------------------------------------------------------------- /djangopress/sitemap.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | from djangopress.core.sitemap import register, autodiscover 3 | from django.contrib.sitemaps import views 4 | 5 | autodiscover() 6 | 7 | sitemap_patterns = [ 8 | url(r'sitemap\.xml', views.sitemap, {'sitemaps': register.get_sitemaps()}, 9 | name='django.contrib.sitemaps.views.sitemap') 10 | ] -------------------------------------------------------------------------------- /djangopress/theme/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/theme/__init__.py -------------------------------------------------------------------------------- /djangopress/theme/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from djangopress.theme.models import Theme 3 | 4 | class ThemeAdmin(admin.ModelAdmin): 5 | list_display = ('display_name', 'slug', 'active', 'name') 6 | admin.site.register(Theme, ThemeAdmin) -------------------------------------------------------------------------------- /djangopress/theme/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ] 11 | 12 | operations = [ 13 | migrations.CreateModel( 14 | name='Theme', 15 | fields=[ 16 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 17 | ('name', models.CharField(unique=True, max_length=30)), 18 | ('slug', models.SlugField(unique=True)), 19 | ('active', models.BooleanField(default=False)), 20 | ('display_name', models.CharField(max_length=100)), 21 | ], 22 | options={ 23 | }, 24 | bases=(models.Model,), 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /djangopress/theme/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/theme/migrations/__init__.py -------------------------------------------------------------------------------- /djangopress/theme/static/themes/default/handheld.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/theme/static/themes/default/handheld.css -------------------------------------------------------------------------------- /djangopress/theme/static/themes/default/print.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/theme/static/themes/default/print.css -------------------------------------------------------------------------------- /djangopress/theme/static/themes/default/style.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/theme/static/themes/default/style.css -------------------------------------------------------------------------------- /djangopress/theme/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/djangopress/theme/templatetags/__init__.py -------------------------------------------------------------------------------- /djangopress/theme/templatetags/theme.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | from djangopress.theme.models import ThemeLibrary 3 | register = template.Library() 4 | 5 | @register.simple_tag() 6 | def theme_folder(): 7 | return ThemeLibrary.get_active().slug -------------------------------------------------------------------------------- /djangopress/theme/tests.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file demonstrates two different styles of tests (one doctest and one 3 | unittest). These will both pass when you run "manage.py test". 4 | 5 | Replace these with more appropriate tests for your application. 6 | """ 7 | 8 | from django.test import TestCase 9 | 10 | class SimpleTest(TestCase): 11 | def test_basic_addition(self): 12 | """ 13 | Tests that 1 + 1 always equals 2. 14 | """ 15 | self.failUnlessEqual(1 + 1, 2) 16 | 17 | __test__ = {"doctest": """ 18 | Another way to test that 1 + 1 is equal to 2. 19 | 20 | >>> 1 + 1 == 2 21 | True 22 | """} 23 | 24 | -------------------------------------------------------------------------------- /djangopress/theme/theme.py: -------------------------------------------------------------------------------- 1 | 2 | theme_meta = { 3 | 'name': 'default', 4 | 'display_name': 'Default Theme', 5 | 'slug': 'default', 6 | } -------------------------------------------------------------------------------- /djangopress/theme/views.py: -------------------------------------------------------------------------------- 1 | # Create your views here. 2 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os, sys 3 | 4 | if __name__ == "__main__": 5 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangopress.settings") 6 | 7 | from django.core.management import execute_from_command_line 8 | 9 | execute_from_command_line(sys.argv) 10 | -------------------------------------------------------------------------------- /www/static/images/icons/browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/images/icons/browser.png -------------------------------------------------------------------------------- /www/static/images/icons/calendar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/images/icons/calendar.png -------------------------------------------------------------------------------- /www/static/images/icons/color-wheel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/images/icons/color-wheel.png -------------------------------------------------------------------------------- /www/static/images/icons/messenger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/images/icons/messenger.png -------------------------------------------------------------------------------- /www/static/images/icons/minimize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/images/icons/minimize.png -------------------------------------------------------------------------------- /www/static/images/icons/pastel-svg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/images/icons/pastel-svg.png -------------------------------------------------------------------------------- /www/static/images/icons/suite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/images/icons/suite.png -------------------------------------------------------------------------------- /www/static/images/icons/toolbar-buttons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/images/icons/toolbar-buttons.png -------------------------------------------------------------------------------- /www/static/images/icons/xrl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/images/icons/xrl.png -------------------------------------------------------------------------------- /www/static/themes/default/handheld.css: -------------------------------------------------------------------------------- 1 | @import "style.general.all.css"; 2 | @import "style.general.handheld.css"; 3 | @import "style.menu.css"; 4 | @import "style.sidebar.all.css"; 5 | @import "style.footer.all.css"; -------------------------------------------------------------------------------- /www/static/themes/default/images/bar-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/bar-small.png -------------------------------------------------------------------------------- /www/static/themes/default/images/bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/bar.png -------------------------------------------------------------------------------- /www/static/themes/default/images/bracket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/bracket.png -------------------------------------------------------------------------------- /www/static/themes/default/images/date.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/date.png -------------------------------------------------------------------------------- /www/static/themes/default/images/empty.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/empty.gif -------------------------------------------------------------------------------- /www/static/themes/default/images/feed-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/feed-hover.png -------------------------------------------------------------------------------- /www/static/themes/default/images/feed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/feed.png -------------------------------------------------------------------------------- /www/static/themes/default/images/footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/footer.png -------------------------------------------------------------------------------- /www/static/themes/default/images/hbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/hbar.png -------------------------------------------------------------------------------- /www/static/themes/default/images/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/header.png -------------------------------------------------------------------------------- /www/static/themes/default/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/icons.png -------------------------------------------------------------------------------- /www/static/themes/default/images/link-bar-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/link-bar-hover.png -------------------------------------------------------------------------------- /www/static/themes/default/images/link-bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/link-bar.png -------------------------------------------------------------------------------- /www/static/themes/default/images/logo-text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/logo-text.png -------------------------------------------------------------------------------- /www/static/themes/default/images/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/menu.png -------------------------------------------------------------------------------- /www/static/themes/default/images/search-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/search-input.png -------------------------------------------------------------------------------- /www/static/themes/default/images/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/search.png -------------------------------------------------------------------------------- /www/static/themes/default/images/side.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/side.png -------------------------------------------------------------------------------- /www/static/themes/default/images/sub-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/sub-menu.png -------------------------------------------------------------------------------- /www/static/themes/default/images/top-level-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/top-level-menu.png -------------------------------------------------------------------------------- /www/static/themes/default/images/top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefisher/djangopress/ab51f444a5f99b1f870527782b974a3d3bc49975/www/static/themes/default/images/top.png -------------------------------------------------------------------------------- /www/static/themes/default/print.css: -------------------------------------------------------------------------------- 1 | #footer { 2 | position:static; 3 | } 4 | 5 | .footer-section, 6 | #sidebar, 7 | #header, 8 | #util-menu, 9 | #djangopress-toolbar { 10 | display:none; 11 | } 12 | 13 | #footer-copyright { 14 | display:block; 15 | } 16 | 17 | #wrapper { 18 | max-width:100%; 19 | padding:0; 20 | } 21 | -------------------------------------------------------------------------------- /www/static/themes/default/style.css: -------------------------------------------------------------------------------- 1 | @import "style.footer.css"; 2 | @import "style.footer.all.css"; 3 | @import "style.front.css"; 4 | @import "style.general.css"; 5 | @import "style.general.all.css"; 6 | @import "style.menu.css"; 7 | @import "style.sidebar.css"; 8 | @import "style.sidebar.all.css"; 9 | @import "style.top-menu.css"; 10 | @import "style.table.css"; 11 | @import "style.toolbar.css"; -------------------------------------------------------------------------------- /www/static/themes/default/style.footer.all.css: -------------------------------------------------------------------------------- 1 | #footer { 2 | font-size:0.75em; 3 | } 4 | 5 | .footer-section h3 { 6 | padding:0 0.25em 0.25em; 7 | margin:0 0.25em 1em; 8 | border-bottom:1px solid #98bc55; 9 | color:#e8f1d7; 10 | text-shadow: #000000 1px 1px 1px; 11 | } 12 | 13 | .footer-section ul { 14 | margin:0 0 0 1em; 15 | padding:0; 16 | /*color:#98bc55;*/ 17 | } 18 | 19 | #footer-copyright { 20 | text-align:center; 21 | padding:1em; 22 | } 23 | 24 | .twitter-follow img { 25 | vertical-align: top; 26 | padding:0 2px; 27 | } 28 | 29 | .footer-detail { 30 | padding:0.5em; 31 | color:#2a4305; 32 | } 33 | 34 | .footer-section a { 35 | color:#2a4305; 36 | } -------------------------------------------------------------------------------- /www/static/themes/default/style.footer.css: -------------------------------------------------------------------------------- 1 | 2 | #footer:before { 3 | content:""; 4 | padding-top:90px; 5 | background:url(images/footer.png) top center no-repeat; 6 | position: absolute; 7 | bottom:150px; 8 | left:0; 9 | width:100%; 10 | z-index:-1; 11 | } 12 | #footer { 13 | background:#71962f; 14 | border-top:1px solid #98bc55; 15 | min-height:150px; 16 | position: absolute; 17 | bottom:0; 18 | left:0; 19 | width:100%; 20 | font-size:0.75em; 21 | } 22 | 23 | #footer-content { 24 | margin:0 auto; 25 | max-width:1100px; 26 | height:100%; 27 | overflow:hidden; 28 | text-overflow:ellipsis; 29 | } 30 | 31 | .footer-section { 32 | width:25%; 33 | float:left; 34 | margin-left:-1px; 35 | height:150px; 36 | max-height:150px; 37 | padding:1em 1em 0 1em; 38 | box-sizing: border-box; 39 | position: relative; 40 | } 41 | 42 | .footer-section:before, 43 | .footer-section:after { 44 | width: 1px; 45 | height:150px; 46 | content: ""; position: absolute; 47 | top:0; 48 | right:-1px; 49 | background:linear-gradient(rgba(255,255,255,0) 5%, rgba(255,255,255,0.6) 50%, rgba(255,255,255,0) 95%); 50 | } 51 | .footer-section:after { 52 | right:-2px; 53 | background:linear-gradient(rgba(0,0,0,0) 5%, rgba(0,0,0,0.3) 50%, rgba(0,0,0,0) 95%); 54 | } 55 | 56 | .footer-section:last-child:after, 57 | .footer-section:last-child:before { 58 | display:none; 59 | } 60 | 61 | .footer-section li { 62 | white-space: nowrap; 63 | width: 100%; 64 | overflow: hidden; 65 | text-overflow:ellipsis; 66 | } 67 | 68 | .footer-section p { 69 | text-overflow:ellipsis; 70 | overflow:hidden; 71 | } 72 | -------------------------------------------------------------------------------- /www/static/themes/default/style.page-edit.css: -------------------------------------------------------------------------------- 1 | .edit-links a { 2 | color:#fff; 3 | padding:1em; 4 | margin:1em; 5 | display:block; 6 | background:#000; 7 | border-radius:6px; 8 | box-shadow: 0px 0px 1px rgba(255, 255, 255, 0.5); 9 | border: 1px solid rgba(0, 0, 0, 0.6); 10 | } 11 | 12 | .edit-links { 13 | text-align:center; 14 | padding:1em; 15 | font-size:1.25em; 16 | position:absolute; 17 | top:-0.5em; 18 | left:-0.5em; 19 | right:-0.5em; 20 | bottom:-0.5em; 21 | min-height:5em; 22 | padding:1em; 23 | background:rgba(0, 0, 0, 0.9); 24 | border-radius:6px; 25 | box-shadow: 0px 0px 1px rgba(255, 255, 255, 0.5); 26 | border: 1px solid rgba(0, 0, 0, 0.6); 27 | } 28 | 29 | .edit-block { 30 | position:relative; 31 | } 32 | 33 | #page-edit-pane { 34 | border:1px solid #000; 35 | background:rgba(0,0,0, 0.8); 36 | border-radius:6px; 37 | color:#fff; 38 | 39 | z-index:10000; 40 | position:absolute; 41 | margin:100px; 42 | top:0; 43 | left:0; 44 | right:0; 45 | } 46 | 47 | #page-edit-pane fieldset { 48 | border:1px solid #fff; 49 | border-radius:6px; 50 | } -------------------------------------------------------------------------------- /www/static/themes/default/style.sidebar.all.css: -------------------------------------------------------------------------------- 1 | .side-bar-content p { 2 | margin:1em 0; 3 | clear:both; 4 | } 5 | 6 | .side-bar-item { 7 | font-size:0.75em; 8 | padding-bottom:6px; 9 | color:#ffffff; 10 | } 11 | 12 | .side-bar-item h3 { 13 | font-family:sans-serif; 14 | padding:5px 10px 12px 10px; 15 | margin:0; 16 | width:230px; 17 | color:#ffffff; 18 | text-shadow: #000000 1px 1px 1px; 19 | background-position:-500px bottom; 20 | } 21 | 22 | .side-bar-item a { 23 | color:#ffffff; 24 | } 25 | 26 | .side-bar-item h4 { 27 | margin:0; 28 | display:inline; 29 | font-size:1em; 30 | } 31 | 32 | .side-bar-item h4 img { 33 | vertical-align: middle; 34 | } 35 | 36 | .side-bar-item h4 a { 37 | font-weight:bold; 38 | font-family:serif; 39 | color:#1d2419; 40 | text-decoration:none; 41 | text-shadow: 0px 1px 1px rgba(255,255,255,0.5); 42 | } 43 | 44 | .side-bar-item li { 45 | list-style-type:circle; 46 | } 47 | 48 | .side-bar-item .fragment { 49 | font-family:sans-serif; 50 | padding:1em 0px; 51 | position:relative; 52 | } 53 | 54 | .side-bar-item .fragment:after, 55 | .side-bar-item .fragment:before { 56 | height: 1px; 57 | width:230px; 58 | content: ""; position: absolute; 59 | left:0; 60 | bottom:-1px; 61 | background:linear-gradient(to right, rgba(255,255,255,0) 5%, rgba(255,255,255,0.6) 50%, rgba(255,255,255,0) 95%); 62 | } 63 | 64 | .side-bar-item .fragment:after { 65 | background:linear-gradient(to right, rgba(0,0,0,0) 5%, rgba(0,0,0,0.3) 50%, rgba(0,0,0,0) 95%); 66 | bottom:-2px; 67 | } 68 | 69 | .side-bar-item .fragment:last-child:after, 70 | .side-bar-item .fragment:last-child:before { 71 | display:none; 72 | } 73 | .side-bar-item .fragment p { 74 | margin:0; 75 | } 76 | .side-bar-item .fragment p a { 77 | text-decoration:underline; 78 | } -------------------------------------------------------------------------------- /www/static/themes/default/style.table.css: -------------------------------------------------------------------------------- 1 | table { 2 | width:100%; 3 | border-radius:6px; 4 | box-shadow: 0px 0px 1px rgb(0, 0, 0); 5 | border: 1px solid rgba(255, 255, 255, 0.1); 6 | } 7 | 8 | table thead, 9 | table tfoot { 10 | font-variant:small-caps; 11 | background: rgba(0, 0, 0, 0.2); 12 | font-weight:bold; 13 | } 14 | 15 | table td, 16 | table th { 17 | padding:2px 5px; 18 | } 19 | table td:nth-child(even) { 20 | background: rgba(0, 0, 0, 0.1); 21 | padding:1px; 22 | } 23 | 24 | table th { 25 | background: linear-gradient(rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.1) 100%); 26 | text-shadow: #000000 1px 1px 2px; 27 | } 28 | 29 | table tr:nth-child(even) { 30 | background: rgba(0, 0, 0, 0.1); 31 | } -------------------------------------------------------------------------------- /www/static/themes/default/style.toolbar.css: -------------------------------------------------------------------------------- 1 | #djangopress-toolbar { 2 | width:100%; 3 | height:30px; 4 | background:#4c7117; 5 | } 6 | 7 | #djangopress-toolbar:after { 8 | display:block; 9 | height:5px; 10 | width:100%; 11 | content:""; 12 | background:url(images/top.png) repeat-x; 13 | } 14 | 15 | #djangopress-toolbar a { 16 | line-height:30px; 17 | padding:2px 5px 2px 26px; 18 | margin:5px; 19 | color:#fff; 20 | text-decoration:none; 21 | text-shadow: #000000 1px 1px 1px; 22 | 23 | background: rgba(255,255,255, 0.25) no-repeat 6px center; 24 | border-radius:6px; 25 | border: 1px solid rgba(0, 0, 0, 0.6); 26 | } 27 | 28 | #djangopress-toolbar a:hover { 29 | background-color: rgba(0, 0, 0, 0.25); 30 | } 31 | 32 | #djangopress-toolbar a.edit { 33 | background-image: url(../../images/pastel-svg/16/pencil.png); 34 | } 35 | 36 | #djangopress-toolbar a.page { 37 | background-image: url(../../images/pastel-svg/16/layout.png); 38 | } -------------------------------------------------------------------------------- /www/static/themes/default/style.top-menu.css: -------------------------------------------------------------------------------- 1 | #top-menu { 2 | max-width:1100px; 3 | margin:0 auto; 4 | height:90px; 5 | line-height:1em; 6 | } 7 | #logo { 8 | margin:0 20px; 9 | float:left; 10 | display:block; 11 | } 12 | #util-menu { 13 | float:right; 14 | margin:0; 15 | padding:0; 16 | } 17 | #util-menu li { 18 | float:left; 19 | display:block; 20 | margin:0; 21 | padding:0; 22 | min-width:50px; 23 | text-align:center; 24 | padding:30px 11px 15px 11px; 25 | margin:0px 0px; 26 | line-height:1em; 27 | } 28 | #util-menu li a { 29 | text-shadow: #000000 1px 1px 1px; 30 | color:#ffffff; 31 | text-decoration:none; 32 | font-size:12px; 33 | font-family:sans-serif; 34 | display:block; 35 | min-width:50px; 36 | background:url(images/link-bar.png) center 15px no-repeat; 37 | padding-top:20px; 38 | font-variant:small-caps; 39 | } 40 | #util-menu li:hover a, #util-menu li a:hover { 41 | background:url(images/link-bar-hover.png) center 15px no-repeat; 42 | color:#7a8863; 43 | } 44 | #util-menu .active, #util-menu .active:hover { 45 | background:url(images/menu.png) 0px 0px no-repeat; 46 | } 47 | #util-menu .active:hover a, #util-menu .active a:hover { 48 | color:#ffffff; 49 | text-shadow: #000000 2px 2px 2px; 50 | } 51 | #util-menu li:hover { 52 | background:url(images/menu.png) -72px 0px no-repeat; 53 | } 54 | 55 | #util-menu .feed a { 56 | background:url(images/feed.png) center 0px no-repeat; 57 | } 58 | #util-menu .feed:hover a, #util-menu .feed a:hover { 59 | background:url(images/feed-hover.png) center 0px no-repeat; 60 | color:#7a8863; 61 | } 62 | --------------------------------------------------------------------------------