diff options
-rw-r--r-- | apps/guide/admin.py | 2 | ||||
-rw-r--r-- | apps/guide/models.py | 31 | ||||
-rw-r--r-- | apps/guide/urls.py | 2 | ||||
-rw-r--r-- | base/__init__.py | 0 | ||||
-rw-r--r-- | base/base_urls.py | 68 | ||||
-rw-r--r-- | base/settings.py | 162 | ||||
-rw-r--r-- | templates/archives/guide.html | 71 |
7 files changed, 301 insertions, 35 deletions
diff --git a/apps/guide/admin.py b/apps/guide/admin.py index efdc7cd..55f713f 100644 --- a/apps/guide/admin.py +++ b/apps/guide/admin.py @@ -16,7 +16,7 @@ class GuideAdmin(OSMGeoAdmin): list_filter = ('pub_date', 'status','region','location') fieldsets = ( ('Note', {'fields': ('title','body_markdown', ('location','region'), 'pub_date', 'status', 'slug','photo_gallery'), 'classes': ('show','extrapretty','wide')}), - ('Pub Location', {'fields': ('dek', 'meta_description','template_name'), 'classes': ('collapse', 'wide')}), + ('Extra', {'fields': ('dek', 'meta_description','template_name', ('image', 'thumbnail')), 'classes': ('collapse', 'wide')}), ) class Media: diff --git a/apps/guide/models.py b/apps/guide/models.py index 16c44fe..793b9f4 100644 --- a/apps/guide/models.py +++ b/apps/guide/models.py @@ -4,6 +4,7 @@ from django.conf import settings from django.contrib.syndication.feeds import Feed from django.contrib.sitemaps import Sitemap from django.template.defaultfilters import truncatewords_html +from PIL import Image from utils import markdown2 as markdown @@ -12,6 +13,12 @@ from locations.models import Location,Region,Country from blog.models import Entry from photos.models import PhotoGallery +def get_upload_path(self, filename): + return "images/guide-images/%s/%s" %(datetime.datetime.today().strftime("%Y"), filename) + +def get_tn_path(self, filename): + return "images/guide-thumbnail/%s/%s" %(datetime.datetime.today().strftime("%Y"), filename) + def image_url_replace(str): str = str.replace('[[base_url]]', settings.IMAGES_URL) return str @@ -47,6 +54,12 @@ class Guide(models.Model): meta_description = models.CharField(max_length=256, null=True, blank=True) template_name = models.IntegerField(choices=TEMPLATES, default=0) tags = TaggableManager(blank=True) + image = models.FileField(upload_to=get_upload_path, null=True,blank=True) + image_height = models.CharField(max_length=20, null=True,blank=True) + image_width = models.CharField(max_length=20, null=True,blank=True) + thumbnail = models.FileField(upload_to=get_tn_path, null=True,blank=True) + thumb_height = models.CharField(max_length=20, null=True,blank=True) + thumb_width = models.CharField(max_length=20, null=True,blank=True) @property @@ -69,12 +82,26 @@ class Guide(models.Model): def get_absolute_url(self): if self.location: - return "/guide/location/%s/%s/" % (self.location.slug, self.slug) + return "/travel-guide/location/%s/%s/" % (self.location.slug, self.slug) else: - return "/guide/%s/" % (self.slug) + return "/travel-guide/%s/" % (self.slug) + def get_thumbnail_url(self): + image_dir, img = self.thumbnail.url.split('guide-thumbnail/')[1].split('/') + return '%sguide-thumbnail/%s/%s' %(settings.IMAGES_URL, image_dir, img) + + def get_image_url(self): + image_dir, img = self.image.url.split('guide-images/')[1].split('/') + return '%sguide-images/%s/%s' %(settings.IMAGES_URL, image_dir, img) def save(self): + #get image dimensions + if self.image: + img = Image.open(self.image) + self.image_width, self.image_height = img.size + #same for thumb + img = Image.open(self.thumbnail) + self.thumb_width, self.thumb_height = img.size md = image_url_replace(self.body_markdown) #run markdown self.body_html = markdown_processor(md) diff --git a/apps/guide/urls.py b/apps/guide/urls.py index b15e7ab..75a24e5 100644 --- a/apps/guide/urls.py +++ b/apps/guide/urls.py @@ -7,5 +7,5 @@ urlpatterns = patterns('', (r'location/$', 'guide.views.location_list'), (r'(?P<page>\d+)/$', 'guide.views.guide_list'), (r'(?P<slug>[-\w]+)/$', 'guide.views.guide_detail'), - (r'', redirect_to, {'url': '/guide/1/'}), + (r'', redirect_to, {'url': '/travel-guide/1/'}), ) diff --git a/base/__init__.py b/base/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/base/__init__.py diff --git a/base/base_urls.py b/base/base_urls.py new file mode 100644 index 0000000..6e9e15f --- /dev/null +++ b/base/base_urls.py @@ -0,0 +1,68 @@ +from django.conf.urls.defaults import * +from django.contrib import admin +from django.views.generic import list_detail +from django.views.generic.simple import redirect_to,direct_to_template +from django.contrib.sitemaps import FlatPageSitemap +from django.conf import settings + +from blog.models import BlogSitemap,LatestFull +from locations.models import WritingbyLocationSitemap +from links.models import LatestLinks +from photos.models import PhotoGallerySitemap +from projects.models.base import ProjectSitemap + +admin.autodiscover() + + +sitemaps = { + 'blog': BlogSitemap, + 'photos': PhotoGallerySitemap, + 'projects': ProjectSitemap +} +feeds = { + 'writing': LatestFull, + 'fblinks' : LatestLinks, +} + +if settings.DEVELOPMENT: + urlpatterns = patterns('', + (r'^media/admin/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT+'/admin'}), + (r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}), + (r'^images/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.IMAGES_ROOT}), + ) +else: + urlpatterns = patterns('') + +# old page redirects +urlpatterns += patterns('', + (r'^2003/nov/02/take-me-your-leader-ii/$', direct_to_template, {'template': 'static/oldcontent.html'}), + (r'^2003/aug/07/take-me-your-leader/$', direct_to_template, {'template': 'static/oldcontent.html'}), + (r'^2004/jan/07/david-foster-wallace-infinity/$', direct_to_template, {'template': 'static/oldcontent.html'}), +) + +urlpatterns += patterns('', + (r'^admin/doc/', include('django.contrib.admindocs.urls')), + (r'^admin/filebrowser/', include('filebrowser.urls')), + (r'^admin/', include(admin.site.urls),), + (r'^grappelli/', include('grappelli.urls')), + (r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': feeds}), + (r'^robots.txt$', direct_to_template, {'template': 'archives/robots.html'}), + (r'^googleb11655cd59dacf3c.html$', direct_to_template, {'template': 'static/gverify.html'}), + (r'^contact/', direct_to_template, {'template': 'details/contact.html'}), + (r'^sitemap.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}), + (r'^writing/', include('blog.urls')), + (r'^projects/', include('projects.urls')), + #Entry detail i.e. /year/month/day/my-title/ + (r'(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>[-\w]+)/$', 'blog.views.entry_detail'), + # locations + (r'^locations/', include('locations.urls')), + (r'^photos/', include('photos.urls')), + (r'^photo/', include('photos.detail_urls')), + (r'^travel-guide/', include('guide.urls')), + # map + (r'^map/', include('locations.urls')), + #about + (r'^about/$', 'blog.views.about'), #'blog.views.home'), + #homepage + (r'^$', 'blog.views.home'), #'blog.views.home'), +) diff --git a/base/settings.py b/base/settings.py new file mode 100644 index 0000000..5cf12cf --- /dev/null +++ b/base/settings.py @@ -0,0 +1,162 @@ +# Django settings for luxagraf. +from os.path import dirname, abspath + +PROJ_ROOT = abspath(dirname(dirname(__file__)))+'/' + + +DEBUG = False +TEMPLATE_DEBUG = DEBUG +DEVELOPMENT = False +ADMINS = ( + ('sng', 'luxagraf@gmail.com'), +) +CONTACT = ( + ('sng', 'sng@luxagraf.net'), +) +MANAGERS = ADMINS + +DATABASES = { + 'default': { + 'NAME': 'luxagraf', + 'ENGINE': 'django.contrib.gis.db.backends.postgis', + 'USER': 'luxagrafe', + 'PASSWORD': 'translinguis#', + 'HOST': 'web62.webfaction.com', + } +} + +#Email Setting for Webfaction +EMAIL_HOST = 'mail2.webfaction.com' +EMAIL_HOST_USER = 'luxagraf' +EMAIL_HOST_PASSWORD = 'translinguis#' +DEFAULT_FROM_EMAIL = 'sng@luxagraf.net' +SEND_BROKEN_LINK_EMAILS = True +SERVER_EMAIL = 'sng@luxagraf.net' +EMAIL_PORT = 25 + +SITE_NAME = 'luxagraf' + +GRAPPELLI_ADMIN_TITLE = 'Luxagraf Admin' + + + +#API key for Google Maps in Admin +MAP_API = "google" +GOOGLE_MAPS_API_KEY = MAP_API_KEY = 'ABQIAAAAEZ0Oz7LFDmdS1OBHm6HLgRQT5Lr-mnFT_29u-YVgAYs_K_u6-BQ627CkPKq44oaHpmSt2497hDj_LQ' +SITE_NAME = 'Luxagraf' +# API key for askimet spam filter +AKISMET_API_KEY = '23decc99e9ed' +# API key for Flickr imports +FLICKR_API_KEY = '7b9d978a440c6ab65a545adc0aa0d693' +FLICKR_USER_ID = '85322932@N00' + +DELICIOUS_USER = 'luxagraf' +DELICIOUS_PASS = 'translinguis#' +TUMBLR_URL = 'luxagraf.tumblr.com' +TUMBLR_PASSWORD = 'translinguis' +TUMBLR_USER ='luxagraf@gmail.com' +TIME_ZONE = 'America/Chicago' + +# Language code for this installation. All choices can be found here: +# http://www.i18nguy.com/unicode/language-identifiers.html +LANGUAGE_CODE = 'en-us' + +SITE_ID = 1 + +# If you set this to False, Django will make some optimizations so as not +# to load the internationalization machinery. +USE_I18N = True + +# Absolute path to the directory that holds media. +# Example: "/home/media/media.lawrence.com/" +MEDIA_ROOT = PROJ_ROOT+'media/' +IMAGES_ROOT = PROJ_ROOT+'media/images/' +STATIC_ROOT = PROJ_ROOT+'static/' + +# URL that handles the media served from MEDIA_ROOT. +# Example: "http://media.lawrence.com" +MEDIA_URL = 'http://media.luxagraf.net/' +IMAGES_URL = 'http://images.luxagraf.net/' +# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a +# trailing slash. +# Examples: "http://foo.com/media/", "/media/". +ADMIN_MEDIA_PREFIX = '/media/admin/' + +# Make this unique, and don't share it with anybody. +SECRET_KEY = '-kzv5^z9@j%cvk6u#lcf&nuga4oiy_-6q^-+#iybt44t_ii-1o' + +#CACHE_BACKEND = 'memcached://174.133.21.78:32348/' +#CACHE_MIDDLEWARE_SECONDS = 3600 +#CACHE_MIDDLEWARE_KEY_PREFIX = 'luxagraf_net' + + +MIDDLEWARE_CLASSES = ( + 'django.middleware.gzip.GZipMiddleware', + #'django.middleware.cache.UpdateCacheMiddleware', + 'django.middleware.common.CommonMiddleware', + # 'django.middleware.cache.FetchFromCacheMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.middleware.doc.XViewMiddleware', + 'pagination.middleware.PaginationMiddleware', + 'fdigg.middleware.FckDiggMiddleware', + #'ssl.middleware.SSLRedirect', + #'debug_toolbar.middleware.DebugToolbarMiddleware', +) +TEMPLATE_CONTEXT_PROCESSORS = ( + 'django.core.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.core.context_processors.debug', + 'django.core.context_processors.media', + "grappelli.context_processors.admin_template_path", +) +ROOT_URLCONF = 'base.base_urls' +INTERNAL_IPS = ( + '67.15.64.48', + '63.251.179.56', + '127.0.0.1' +) + +TEMPLATE_DIRS = ( + PROJ_ROOT+'templates', + PROJ_ROOT+'lib/templates', + PROJ_ROOT+'lib/grappelli/templates', + #PROJ_ROOT+'lib/debug_toolbar/templates', + # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". + # Always use forward slashes, even on Windows. + # Don't forget to use absolute paths, not relative paths. +) +TEMPLATE_LOADERS = ( + ('django.template.loaders.cached.Loader', ( + 'django.template.loaders.filesystem.Loader', + 'django.template.loaders.app_directories.Loader', + )), +) +INSTALLED_APPS = ( + 'grappelli', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.sites', + 'django.contrib.admin', + 'django.contrib.sitemaps', + 'django.contrib.gis', + 'filebrowser', + 'locations', + 'blog', + 'photos', + #'tagging', + 'taggit', + 'chunks', + 'links', + 'pagination', + 'templatetags', + 'contact_form', + 'projects', + 'guide' + +) +try: + from settings_local import * +except: + pass diff --git a/templates/archives/guide.html b/templates/archives/guide.html index e880343..27ac756 100644 --- a/templates/archives/guide.html +++ b/templates/archives/guide.html @@ -2,41 +2,50 @@ {% load typogrify %} {% load pagination_tags %} -{% block pagetitle %}Luxagraf | {% if region %}Travel Writing from {{region.name|title|smartypants|safe}}{%else%}Travel Writing from Around the World {%endif%} Page {{page}}{% endblock %} -{% block metadescription %}{% if region %}Travel writing, essays and dispatches from {{region.name|title|smartypants|safe}}{%else%}Travel writing, essays and dispatches from around the world{%endif%} Page {{page}}{% endblock %} -{%block bodyid%}id="writing"{%endblock%} - - -{% block primary %}<section id="page-header"> - <h1 class="hide">{% if region %}Writings from {%if region.name == 'United States'%}the United States{%else%}{{region.name|title|smartypants|safe}}{%endif%}{%else%}Writing {%endif%}</h1> - <nav class="bl"> - <ul id="breadcrumbs" itemscope itemtype="http://data-vocabulary.org/Breadcrumb"> - <li><a href="/" title="luxagraf homepage" itemprop="url"><span itemprop="title">Home</span></a> → </li> - {% if region %}{%if region.name == 'United States'%} <li><a href="/writing/" title="See all Writing" itemprop="url"><span itemprop="title">Writing</span></a> →</li> - <li itemprop="title">the United States</li>{%else%}<li><a href="/writing/" title="See all Writing" itemprop="url"><span>Writing</span></a> →</li> - <li>{{region.name|title|smartypants|safe}}</li>{%endif%}{%else%}<li>Writing </li>{%endif%} - </ul> - </nav> +{% block pagetitle %}Luxagraf | {% if region %}Travel Guide {{region.name|title|smartypants|safe}}{%else%} Travel Guides, Tips, Tricks and Recommendations {%endif%} Page {{page}}{% endblock %} +{% block metadescription %}{% if region %}A Travel Guide, Tips, Tricks and Recommendations for {{region.name|title|smartypants|safe}}{%else%}Travel Guides, Tips, Tricks and Recommendations {%endif%} Page {{page}}{% endblock %} +{%block bodyid%}id="guide-archive" class="guide"{%endblock%} + + +{% block primary %}<ul class="bl" id="breadcrumbs" itemscope itemtype="http://data-vocabulary.org/Breadcrumb"> + <li><a href="/" title="luxagraf homepage" itemprop="url"><span itemprop="title">Home</span></a> → </li> + {% if region %}{%if region.name == 'United States'%} <li><a href="/guide/1/" title="See all Guides" itemprop="url"><span itemprop="title">Travel Guides</span></a> →</li> + <li itemprop="title">United States</li>{%else%}<li><a href="/guide/1/" title="See all Guides" itemprop="url"><span>Travel Guides</span></a> →</li> + <li>{{region.name|title|smartypants|safe}}</li>{%endif%}{%else%}<li>Travel Guides</li>{%endif%} + </ul> + + <section class="intro"> + <h1>Travel Guides</h1> + <h2>What I Know About Where I've Been</h2> + <div class="formatted"> + <p>The essays on luxagraf rarely offer much travel advice. I don't often write about places I stay, where I eat, the gear I carry or even how to get from here to there. At the same time I always save business cards and write down addresses almost everywhere I go. + Until now I haven't really done anything with that information, save tell a few friends headed in similar directions. So I decided to created this, the <strong>travel guide</strong> section, so you can know what I know. I even busted out the video camera for a few of these. Just bear in mind that this is my experience, yours may be very different. That's okay.</p></div> </section> - <section id="writing-archive" class="archive"> {% autopaginate object_list 10 %} {% for object in object_list %} - <article> - <h1><a href="{{object.get_absolute_url}}" title="{%if object.title_keywords%}{{object.title_keywords}}{%else%}{{object.title}}{%endif%}">{{object.title|smartypants|widont|safe}}</a></h1> - <div class="img"> - <a href="{{object.get_absolute_url}}" title="{{object.title}}"><img src="{{object.get_image_url}}" alt="{{ object.title }}" width="{{object.image_width}}" height="{{object.image_height}}" class="post-image" /></a> - </div> - <div class="dateline"> - <p class="location bl" itemprop="geo" itemscope itemtype="http://data-vocabulary.org/Geo">{% if object.country_name == "United States" %}{{object.location_name|smartypants|safe}}, <a href="/writing/united-states/1/" title="travel writing from the United States">{{object.state_name}}</a>{%else%}{{object.location_name|smartypants|safe}}, <a href="/writing/{{object.country_name|slugify}}/1/" title="travel writing from {{object.country_name}}">{{object.country_name}}</a>{%endif%} - <meta itemprop="latitude" content="{{object.latitude}}" /> - <meta itemprop="longitude" content="{{object.longitude}}" /></p> - <time datetime="{{object.pub_date|date:'c'}}">{{object.pub_date|date:"m/d/y"}}</time> - </div> - <p class="hyphenate">{{object.dek|safe}}</p> + + + <section id="guides" class=""> {% autopaginate object_list 10 %} {% for object in object_list %} + <article id="guide-10{{object.id}}"> + <div class="meta bl"> + <div class="tags">Filed Under: <a href="{{object.get_absolute_url}}" title="{{object.title}}">General</a>, <a href="{{object.get_absolute_url}}" title="{{object.title}}">Gear</a></div> + <time pubdate class="hide" datetime="{{object.pub_date|date:'c'}}">{{object.pub_date|date:"m/d/y"}}</time> + <a href="{{object.get_absolute_url}}" title="{{object.title}}"><img src="{{object.get_thumbnail_url}}" alt="{{ object.title }}" width="150" class="{{object.image_width}}" height="98" claaa="{{object.image_height}}" class="guide-thumb" /></a> + </div> + <div class="guide-dek"> + <h1><a href="{{object.get_absolute_url}}" title="{{object.title}}">{{object.title|smartypants|widont|safe}}</a></h1> + <p class="hyphenate">{{object.dek|safe}}</p> + </div> </article> {% endfor %} </section> - <nav id="pagination">{% paginate %} - </nav> + <div id="pagination">{% paginate %} + </div> {% endblock %} -{% block js %}<script src="{{MEDIA_URL}}js/hyphenate.min.js" type="text/javascript"></script>{% endblock%}
\ No newline at end of file +{% block js %}<script src="{{MEDIA_URL}}js/hyphenate.min.js" type="text/javascript"></script>{% endblock%} + + + +{% if object.location %}<p class="location" itemprop="geo" itemscope itemtype="http://data-vocabulary.org/Geo">{% if object.country_name == "United States" %}{{object.location_name|smartypants|safe}}, <a href="/writing/united-states/1/" title="travel writing from the United States">{{object.state_name}}</a>{%else%}{{object.location_name|smartypants|safe}}, <a href="/writing/{{object.country_name|slugify}}/1/" title="travel writing from {{object.country_name}}">{{object.country_name}}</a>{%endif%} + <meta itemprop="latitude" content="{{object.latitude}}" /> + <meta itemprop="longitude" content="{{object.longitude}}" /></p>{%endif%} |