Skip to content

Commit

Permalink
bump version to 1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
razisayyed committed Mar 26, 2019
1 parent 63c979d commit b710791
Show file tree
Hide file tree
Showing 11 changed files with 272 additions and 100 deletions.
103 changes: 64 additions & 39 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,43 +73,63 @@ Add the following to your settings file:

.. code-block:: python
ADS_GOOGLE_ADSENSE_CLIENT = 'ca-pub-xxxxxxxxxxxxxxxx' # OPTIONAL - DEFAULT TO None
ADS_ZONES = {
'header': {
'name': _('Header'),
'ad_size': {
'xs': '720x150',
'sm': '800x90',
'md': '800x90',
'lg': '800x90'
},
'google_adsense_slot': 'xxxxxxxxx', # OPTIONAL - DEFAULT TO None
'google_adsense_format': 'auto', # OPTIONAL - DEFAULT TO None
},
'content': {
'name': _('Content'),
'ad_size': {
'xs': '720x150',
'sm': '800x90',
'md': '800x90',
'lg': '800x90'
},
'google_adsense_slot': 'xxxxxxxxx', # OPTIONAL - DEFAULT TO None
'google_adsense_format': 'auto', # OPTIONAL - DEFAULT TO None
},
'sidebar': {
'name': _('Sidebar'),
'ad_size': {
'xs': '720x150',
'sm': '800x90',
'md': '800x90',
'lg': '800x90'
},
'google_adsense_slot': 'xxxxxxxxx', # OPTIONAL - DEFAULT TO None
'google_adsense_format': 'auto', # OPTIONAL - DEFAULT TO None
},
}
ADS_GOOGLE_ADSENSE_CLIENT = None # 'ca-pub-xxxxxxxxxxxxxxxx'
ADS_ZONES = {
'header': {
'name': gettext('Header'),
'ad_size': {
'xs': '720x150',
'sm': '800x90',
'md': '800x90',
'lg': '800x90',
'xl': '800x90'
},
'google_adsense_slot': None, # 'xxxxxxxxx',
'google_adsense_format': None, # 'auto'
},
'content': {
'name': gettext('Content'),
'ad_size': {
'xs': '720x150',
'sm': '800x90',
'md': '800x90',
'lg': '800x90',
'xl': '800x90'
},
'google_adsense_slot': None, # 'xxxxxxxxx',
'google_adsense_format': None, # 'auto'
},
'sidebar': {
'name': gettext('Sidebar'),
'ad_size': {
'xs': '720x150',
'sm': '800x90',
'md': '800x90',
'lg': '800x90',
'xl': '800x90'
}
}
}
ADS_DEFAULT_AD_SIZE = '720x150'
ADS_DEVICES = (
('xs', _('Extra small devices')),
('sm', _('Small devices')),
('md', _('Medium devices (Tablets)')),
('lg', _('Large devices (Desktops)')),
('xl', _('Extra large devices (Large Desktops)')),
)
ADS_VIEWPORTS = {
'xs': 'd-block img-fluid d-sm-none',
'sm': 'd-none img-fluid d-sm-block d-md-none',
'md': 'd-none img-fluid d-md-block d-lg-none',
'lg': 'd-none img-fluid d-lg-block d-xl-none',
'xl': 'd-none img-fluid d-xl-block',
}
Where each element in ``ADS_ZONES`` defines a ``zone`` that can be used in your templates to display ads. Each zone must have a name to be used in the admin interface when adding ads, and sizes to be used to display the ad images in templates.

Expand Down Expand Up @@ -154,6 +174,11 @@ use ``render_ads_zone`` in your template where you want your ads to appear:
Changelog:
----------

1.0.0 (2019-03-26):

- major change in functionality (switch to JS approach in rendering templates). You need jquery to be installed in frontend to use django-ads.
- Note: templates/ads/tags/render_ads_zone.html has been changed. If you use a custom template, then please take a look at the new version.

0.2.1 (2018-07-26): (Special Thanks to `@GabrielDumbrava <https://github.com/GabrielDumbrava>`_
)

Expand All @@ -167,8 +192,8 @@ Changelog:

- add long_description to setup.py

0.2.0 (2018-02-05) (Special Thanks to `@ataylor32 <https://github.com/ataylor32>`_
):
0.2.0 (2018-02-05): (Special Thanks to `@ataylor32 <https://github.com/ataylor32>`_
)

- add Django 2.0 support
- add missing dependency (Pillow)
Expand Down
2 changes: 1 addition & 1 deletion ads/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
default_app_config = 'ads.apps.AdsConfig'

__version__ = '0.2.2'
__version__ = '1.0.0'
26 changes: 19 additions & 7 deletions ads/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ class Meta:
'xs': '720x150',
'sm': '800x90',
'md': '800x90',
'lg': '800x90'
'lg': '800x90',
'xl': '800x90'
},
'google_adsense_slot': None, # 'xxxxxxxxx',
'google_adsense_format': None, # 'auto'
Expand All @@ -31,7 +32,8 @@ class Meta:
'xs': '720x150',
'sm': '800x90',
'md': '800x90',
'lg': '800x90'
'lg': '800x90',
'xl': '800x90'
},
'google_adsense_slot': None, # 'xxxxxxxxx',
'google_adsense_format': None, # 'auto'
Expand All @@ -42,16 +44,26 @@ class Meta:
'xs': '720x150',
'sm': '800x90',
'md': '800x90',
'lg': '800x90'
'lg': '800x90',
'xl': '800x90'
}
}
}

DEFAULT_AD_SIZE = '720x150'

DEVICES = (
('xs', _('Smartphones')),
('sm', _('Tablets')),
('md', _('Small Desktops')),
('lg', _('Large Desktops'))
('xs', _('Extra small devices')),
('sm', _('Small devices')),
('md', _('Medium devices (Tablets)')),
('lg', _('Large devices (Desktops)')),
('xl', _('Extra large devices (Large Desktops)')),
)

VIEWPORTS = {
'xs': 'd-block img-fluid d-sm-none',
'sm': 'd-none img-fluid d-sm-block d-md-none',
'md': 'd-none img-fluid d-md-block d-lg-none',
'lg': 'd-none img-fluid d-lg-block d-xl-none',
'xl': 'd-none img-fluid d-xl-block',
}
25 changes: 25 additions & 0 deletions ads/mixins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from django.http import JsonResponse


class JSONResponseMixin:
"""
A mixin that can be used to render a JSON response.
"""
def render_to_json_response(self, context, **response_kwargs):
"""
Returns a JSON response, transforming 'context' to make the payload.
"""
return JsonResponse(
self.get_data(context),
**response_kwargs
)

def get_data(self, context):
"""
Returns an object that will be serialized as JSON by json.dumps().
"""
# Note: This is *EXTREMELY* naive; in reality, you'll need
# to do much more complex handling to ensure that arbitrary
# objects -- such as Django model instances or querysets
# -- can be serialized as JSON.
return context
50 changes: 50 additions & 0 deletions ads/static/ads/ads.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
$(function() {
var zones = [];
$('div[data-django-ads-zone]').each(function() {
var zone = $(this).data('django-ads-zone');
zones.push(zone);
});
var url = Urls['ads:ad-impression']();
$.get(url, { zones: zones }, function( data ) {
var viewports = data.viewports;
Object.keys(data.zones).forEach(key => {
var $ad_container = $('div[data-django-ads-zone="'+key+'"]');
var zone = data.zones[key];
var html = '';
if(zone.ad !== null) {
ad = zone.ad;
html = '<a href="'+ad.url+'" target="_blank">';
Object.keys(ad['images']).forEach(key => {
var img = ad['images'][key];
html += '<img src="'+img.url+'" class="'+viewports[key]+'"/>';
});
html += '</a>';
$ad_container.html(html);
} else if ('google_adsense_slot' in zone.conf && 'google_adsense_format' in zone.conf) {
var google_adsense_client = data.google_adsense_client;
var google_adsense_slot = zone.conf.google_adsense_slot;
var google_adsense_format = zone.conf.google_adsense_format;
html = '<ins class="adsbygoogle" \
style="display:block" \
data-ad-client="'+google_adsense_client+'" \
data-ad-slot="'+google_adsense_slot+'" \
data-ad-format="'+google_adsense_format+'"></ins>';
$ad_container.html(html);
(adsbygoogle = window.adsbygoogle || []).push({});
}
if(html !== '') {
var extra_classes = $ad_container.data('django-ads-extra-classes');
$ad_container.addClass(extra_classes);
}
});
/*
<ins class="adsbygoogle"
style="display:block"
data-ad-client="{{ google_adsense_client }}"
data-ad-slot="{{ zone.google_adsense_slot }}"
data-ad-format="{{ zone.google_adsense_format|default:'auto' }}"></ins>
<script>(adsbygoogle = window.adsbygoogle || []).push({});</script>
*/
});

});
20 changes: 3 additions & 17 deletions ads/templates/ads/tags/render_ads_zone.html
Original file line number Diff line number Diff line change
@@ -1,17 +1,3 @@
{% load sekizai_tags %}{% spaceless %}
{% if ad %}
{% for image in ad.images.all %}
<a href="{% url 'ads:ad-click' ad.id %}" target="_blank" rel="nofollow" title="{{ ad.title }}" class="django-ads-ad visible-{{ image.device }}">
<img src="{{ image.image.url }}" class="img-responsive" />
</a>
{% endfor %}
{% elif google_adsense_client and zone.google_adsense_slot %}
{% addtoblock "js" %}<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>{% endaddtoblock %}
<ins class="adsbygoogle"
style="display:block"
data-ad-client="{{ google_adsense_client }}"
data-ad-slot="{{ zone.google_adsense_slot }}"
data-ad-format="{{ zone.google_adsense_format|default:'auto' }}"></ins>
<script>(adsbygoogle = window.adsbygoogle || []).push({});</script>
{% endif %}
{% endspaceless %}
{% load static sekizai_tags %}
<div data-django-ads-zone="{{ zone|safe }}" data-django-ads-extra-classes="{{ extra_classes|safe }}"></div>
{% addtoblock "js" %}<script defer src='{% static 'ads/ads.js' %}'></script>{% endaddtoblock %}
23 changes: 3 additions & 20 deletions ads/templatetags/ads_tags.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
from __future__ import unicode_literals

from django import template
from django.conf import settings
from django.utils import timezone

from ads.conf import settings
from ads.models import Ad, Impression
from ads.utils import get_client_ip


register = template.Library()

Expand All @@ -19,23 +16,9 @@ def render_ads_zone(context, zone):
{% load ads_tags %}
{% render_zone 'zone' %}
"""

# Retrieve random ad for the zone based on weight
ad = Ad.objects.random_ad(zone)

if ad is not None:
request = context['request']
if request.session.session_key:
impression, created = Impression.objects.get_or_create(
ad=ad,
session_id=request.session.session_key,
defaults={
'impression_date': timezone.now(),
'source_ip': get_client_ip(request),
})
context.update({
'ad': ad,
'google_adsense_client': settings.ADS_GOOGLE_ADSENSE_CLIENT,
'zone': settings.ADS_ZONES.get(zone, None)
'zone': zone,
'zone_info': settings.ADS_ZONES.get(zone, None)
})
return context
7 changes: 5 additions & 2 deletions ads/urls.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from ads.views import AdClickView
from ads.views import AdImpressionView, AdClickView
from django.conf.urls import url


app_name = 'ads'
urlpatterns = [
url(r'^(?P<pk>\d+)/$', AdClickView.as_view(), name='ad-click'),
url(r'^(?P<pk>\d+)/$',
AdClickView.as_view(), name='ad-click'),
url(r'^get-ads-by-zones/$',
AdImpressionView.as_view(), name='ad-impression'),
]
31 changes: 29 additions & 2 deletions ads/utils.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from django.conf import settings
from django.utils.translation import gettext_lazy
from django.utils import timezone
from django.utils.translation import gettext_lazy as _

from ads.models import Click, Impression


def get_zones_choices():
for key in sorted(settings.ADS_ZONES):
yield (key, gettext_lazy(settings.ADS_ZONES[key].get('name', 'Undefined')))
yield (key, _(settings.ADS_ZONES[key].get('name', 'Undefined')))


def get_client_ip(request):
Expand All @@ -14,3 +17,27 @@ def get_client_ip(request):
else:
ip = request.META.get('REMOTE_ADDR', '')
return ip


def update_clicks(ad, request):
if ad is not None:
if request.session.session_key:
impression, created = Click.objects.get_or_create(
ad=ad,
session_id=request.session.session_key,
defaults={
'click_date': timezone.now(),
'source_ip': get_client_ip(request),
})


def update_impressions(ad, request):
if ad is not None:
if request.session.session_key:
impression, created = Impression.objects.get_or_create(
ad=ad,
session_id=request.session.session_key,
defaults={
'impression_date': timezone.now(),
'source_ip': get_client_ip(request),
})
Loading

0 comments on commit b710791

Please sign in to comment.