././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1701810659.1261919 django-favicon-plus-reloaded-1.2/0000755000175000017500000000000014533710743016430 5ustar00wethjowethjo././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1588607173.0 django-favicon-plus-reloaded-1.2/AUTHORS.txt0000644000175000017500000000020113654034305020303 0ustar00wethjowethjoyannik-ammann bashu Calzzetta philippeowagner walterrenner arthru raphaa Michał Pasternak (mpasternak) ZugBahnHof Natureshadow ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1629904793.0 django-favicon-plus-reloaded-1.2/LICENSE0000644000175000017500000000222614111457631017433 0ustar00wethjowethjoCopyright (c) 2012 arteria GmbH Copyright (c) 2020 Julian Leucker Copyright (c) 2021 Dominik George Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1588607173.0 django-favicon-plus-reloaded-1.2/MANIFEST.in0000644000175000017500000000032413654034305020161 0ustar00wethjowethjoinclude README.md include LICENSE include requirements.txt recursive-include favicon/templates * recursive-include favicon *.html *.png *.gif *js *.css *jpg *jpeg *svg *py global-exclude *.orig *.pyc *.log *.swp ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1701810659.1261919 django-favicon-plus-reloaded-1.2/PKG-INFO0000644000175000017500000001523214533710743017530 0ustar00wethjowethjoMetadata-Version: 2.1 Name: django-favicon-plus-reloaded Version: 1.2 Summary: Simple Django app which allows you to upload a image and it renders a wide variety for html link tags to display the favicon Home-page: https://edugit.org/AlekSIS/libs/django-favicon-plus Author: arteria GmbH Author-email: arteria@arteria.ch Maintainer: AlekSIS Team Maintainer-email: aleksis-dev@lists.teckids.org License: MIT Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Web Environment Classifier: Framework :: Django Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.12 Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content Description-Content-Type: text/markdown License-File: LICENSE License-File: AUTHORS.txt Requires-Dist: django<6.0,>=4.2.0 Requires-Dist: pillow<11.0,>=10.0.0 # django-favicon-plus Django favicon plus is a simple django app which allows you to upload a image and it renders a wide variety for html link tags to display the favicon. These different tags are used for bookmark links on mobile devices or they appear if you favorite a website in your browser. This version is a fork of the [original version from arteria GmbH](https://github.com/arteria/django-favicon-plus/) due to lack of maintenance. ## How to use: Install django-favicon using PIP. ```shell pip install django-favicon-plus-reloaded pip install git+https://edugit.org/AlekSIS/libs/django-favicon-plus.git ``` Add app to `INSTALLED_APPS` List in your `settings.py` file, make sure `sites`-app is also installed, a URL is specified in the admin backend and you specify your site in settings.py with `SITE_ID = `. ```python INSTALLED_APPS = ( ... 'django.contrib.sites', ... 'favicon', ... ) ``` The default `FAVICON_CONFIG` look like this, if you want something else you can define it in your settings.py. The key of the dictionary is the value for the `rel` attribute of the link tag, while the list in the value are the sizes for the `size` attribute and the image resizing. ```python FAVICON_CONFIG = { 'shortcut icon': [16 ,32 ,48 ,128, 192], 'touch-icon': [196], 'icon': [196], 'apple-touch-icon': [57, 72, 114, 144, 180], 'apple-touch-icon-precomposed': [57, 72, 76, 114, 120, 144, 152,180], } ``` Please make sure you have specified a `MEDIA_URL` in `settings.py` and your root `urlconf` looks like this: ```python urlpatterns = [ path('admin/', admin.site.urls), ..., ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) ``` You can also provide a `FAVICON_PATH` in your `settings.py` to specify the folder name of your favicon folder. The default is `favicon` Upload an image in the admin backend --> all the size will be created, its best to take a larger base favicon. Use the templatetag in your base.html ```html+django {% load favtags %} {% place_favicon %} ``` this will create: ```html ``` ## Management You can upload multiple images, but only one is set as favicon and used. ## Contribution If you want to contribute something send an MR. # Source ### Based on [Favicon Cheat Sheet on github](https://github.com/audreyr/favicon-cheat-sheet) ### Favicon 16x16 .ico or better .png ```html ``` ### apple-touch-icon(-precomposed) 57x57, 72x72, 114x114, and 144x144 highest resolution for ipad retina 144x144.png precomposed(=iOS won’t add any effects to the icon) ```html ``` Android versions 1.5 and 1.6 will read the second tag (with "-precomposed"), and versions 2.1 and newer will read the first tag. Google's specifications say that you should use 48x48 pixel PNGs, but you can use a large image (128x128), like Google does for its own apps. https://mathiasbynens.be/notes/touch-icons ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1588607173.0 django-favicon-plus-reloaded-1.2/README.md0000644000175000017500000001262413654034305017710 0ustar00wethjowethjo# django-favicon-plus Django favicon plus is a simple django app which allows you to upload a image and it renders a wide variety for html link tags to display the favicon. These different tags are used for bookmark links on mobile devices or they appear if you favorite a website in your browser. This version is a fork of the [original version from arteria GmbH](https://github.com/arteria/django-favicon-plus/) due to lack of maintenance. ## How to use: Install django-favicon using PIP. ```shell pip install django-favicon-plus-reloaded pip install git+https://edugit.org/AlekSIS/libs/django-favicon-plus.git ``` Add app to `INSTALLED_APPS` List in your `settings.py` file, make sure `sites`-app is also installed, a URL is specified in the admin backend and you specify your site in settings.py with `SITE_ID = `. ```python INSTALLED_APPS = ( ... 'django.contrib.sites', ... 'favicon', ... ) ``` The default `FAVICON_CONFIG` look like this, if you want something else you can define it in your settings.py. The key of the dictionary is the value for the `rel` attribute of the link tag, while the list in the value are the sizes for the `size` attribute and the image resizing. ```python FAVICON_CONFIG = { 'shortcut icon': [16 ,32 ,48 ,128, 192], 'touch-icon': [196], 'icon': [196], 'apple-touch-icon': [57, 72, 114, 144, 180], 'apple-touch-icon-precomposed': [57, 72, 76, 114, 120, 144, 152,180], } ``` Please make sure you have specified a `MEDIA_URL` in `settings.py` and your root `urlconf` looks like this: ```python urlpatterns = [ path('admin/', admin.site.urls), ..., ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) ``` You can also provide a `FAVICON_PATH` in your `settings.py` to specify the folder name of your favicon folder. The default is `favicon` Upload an image in the admin backend --> all the size will be created, its best to take a larger base favicon. Use the templatetag in your base.html ```html+django {% load favtags %} {% place_favicon %} ``` this will create: ```html ``` ## Management You can upload multiple images, but only one is set as favicon and used. ## Contribution If you want to contribute something send an MR. # Source ### Based on [Favicon Cheat Sheet on github](https://github.com/audreyr/favicon-cheat-sheet) ### Favicon 16x16 .ico or better .png ```html ``` ### apple-touch-icon(-precomposed) 57x57, 72x72, 114x114, and 144x144 highest resolution for ipad retina 144x144.png precomposed(=iOS won’t add any effects to the icon) ```html ``` Android versions 1.5 and 1.6 will read the second tag (with "-precomposed"), and versions 2.1 and newer will read the first tag. Google's specifications say that you should use 48x48 pixel PNGs, but you can use a large image (128x128), like Google does for its own apps. https://mathiasbynens.be/notes/touch-icons ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1701810659.1261919 django-favicon-plus-reloaded-1.2/django_favicon_plus_reloaded.egg-info/0000755000175000017500000000000014533710743025773 5ustar00wethjowethjo././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1701810659.0 django-favicon-plus-reloaded-1.2/django_favicon_plus_reloaded.egg-info/PKG-INFO0000644000175000017500000001523214533710743027073 0ustar00wethjowethjoMetadata-Version: 2.1 Name: django-favicon-plus-reloaded Version: 1.2 Summary: Simple Django app which allows you to upload a image and it renders a wide variety for html link tags to display the favicon Home-page: https://edugit.org/AlekSIS/libs/django-favicon-plus Author: arteria GmbH Author-email: arteria@arteria.ch Maintainer: AlekSIS Team Maintainer-email: aleksis-dev@lists.teckids.org License: MIT Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Web Environment Classifier: Framework :: Django Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.12 Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content Description-Content-Type: text/markdown License-File: LICENSE License-File: AUTHORS.txt Requires-Dist: django<6.0,>=4.2.0 Requires-Dist: pillow<11.0,>=10.0.0 # django-favicon-plus Django favicon plus is a simple django app which allows you to upload a image and it renders a wide variety for html link tags to display the favicon. These different tags are used for bookmark links on mobile devices or they appear if you favorite a website in your browser. This version is a fork of the [original version from arteria GmbH](https://github.com/arteria/django-favicon-plus/) due to lack of maintenance. ## How to use: Install django-favicon using PIP. ```shell pip install django-favicon-plus-reloaded pip install git+https://edugit.org/AlekSIS/libs/django-favicon-plus.git ``` Add app to `INSTALLED_APPS` List in your `settings.py` file, make sure `sites`-app is also installed, a URL is specified in the admin backend and you specify your site in settings.py with `SITE_ID = `. ```python INSTALLED_APPS = ( ... 'django.contrib.sites', ... 'favicon', ... ) ``` The default `FAVICON_CONFIG` look like this, if you want something else you can define it in your settings.py. The key of the dictionary is the value for the `rel` attribute of the link tag, while the list in the value are the sizes for the `size` attribute and the image resizing. ```python FAVICON_CONFIG = { 'shortcut icon': [16 ,32 ,48 ,128, 192], 'touch-icon': [196], 'icon': [196], 'apple-touch-icon': [57, 72, 114, 144, 180], 'apple-touch-icon-precomposed': [57, 72, 76, 114, 120, 144, 152,180], } ``` Please make sure you have specified a `MEDIA_URL` in `settings.py` and your root `urlconf` looks like this: ```python urlpatterns = [ path('admin/', admin.site.urls), ..., ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) ``` You can also provide a `FAVICON_PATH` in your `settings.py` to specify the folder name of your favicon folder. The default is `favicon` Upload an image in the admin backend --> all the size will be created, its best to take a larger base favicon. Use the templatetag in your base.html ```html+django {% load favtags %} {% place_favicon %} ``` this will create: ```html ``` ## Management You can upload multiple images, but only one is set as favicon and used. ## Contribution If you want to contribute something send an MR. # Source ### Based on [Favicon Cheat Sheet on github](https://github.com/audreyr/favicon-cheat-sheet) ### Favicon 16x16 .ico or better .png ```html ``` ### apple-touch-icon(-precomposed) 57x57, 72x72, 114x114, and 144x144 highest resolution for ipad retina 144x144.png precomposed(=iOS won’t add any effects to the icon) ```html ``` Android versions 1.5 and 1.6 will read the second tag (with "-precomposed"), and versions 2.1 and newer will read the first tag. Google's specifications say that you should use 48x48 pixel PNGs, but you can use a large image (128x128), like Google does for its own apps. https://mathiasbynens.be/notes/touch-icons ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1701810659.0 django-favicon-plus-reloaded-1.2/django_favicon_plus_reloaded.egg-info/SOURCES.txt0000644000175000017500000000130114533710743027652 0ustar00wethjowethjoAUTHORS.txt LICENSE MANIFEST.in README.md requirements.txt setup.py django_favicon_plus_reloaded.egg-info/PKG-INFO django_favicon_plus_reloaded.egg-info/SOURCES.txt django_favicon_plus_reloaded.egg-info/dependency_links.txt django_favicon_plus_reloaded.egg-info/not-zip-safe django_favicon_plus_reloaded.egg-info/requires.txt django_favicon_plus_reloaded.egg-info/top_level.txt favicon/__init__.py favicon/admin.py favicon/models.py favicon/migrations/0001_initial.py favicon/migrations/0002_favicon_site.py favicon/migrations/0003_site_manager.py favicon/migrations/0004_faviconimg_favicon_size_rel_unique.py favicon/migrations/__init__.py favicon/templatetags/__init__.py favicon/templatetags/favtags.py././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1701810659.0 django-favicon-plus-reloaded-1.2/django_favicon_plus_reloaded.egg-info/dependency_links.txt0000644000175000017500000000000114533710743032041 0ustar00wethjowethjo ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1688253127.0 django-favicon-plus-reloaded-1.2/django_favicon_plus_reloaded.egg-info/not-zip-safe0000644000175000017500000000000114450131307030210 0ustar00wethjowethjo ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1701810659.0 django-favicon-plus-reloaded-1.2/django_favicon_plus_reloaded.egg-info/requires.txt0000644000175000017500000000005014533710743030366 0ustar00wethjowethjodjango<6.0,>=4.2.0 pillow<11.0,>=10.0.0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1701810659.0 django-favicon-plus-reloaded-1.2/django_favicon_plus_reloaded.egg-info/top_level.txt0000644000175000017500000000001014533710743030514 0ustar00wethjowethjofavicon ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1701810659.122192 django-favicon-plus-reloaded-1.2/favicon/0000755000175000017500000000000014533710743020055 5ustar00wethjowethjo././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1701810541.0 django-favicon-plus-reloaded-1.2/favicon/__init__.py0000644000175000017500000000002414533710555022163 0ustar00wethjowethjo__version__ = '1.2' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1588607173.0 django-favicon-plus-reloaded-1.2/favicon/admin.py0000644000175000017500000000133713654034305021517 0ustar00wethjowethjofrom django.contrib import admin from favicon.models import Favicon, FaviconImg class FaviconAdmin(admin.ModelAdmin): list_display = ('title', 'isFavicon') admin.site.register(Favicon, FaviconAdmin) class FaviconImgAdmin(admin.ModelAdmin): list_display = ('faviconFK', 'rel', 'size', 'faviconImage') def queryset(self, request): qs = super(FaviconImgAdmin, self).queryset(request) isFavicon = Favicon.objects.filter(isFavicon=True) if not len(isFavicon) == 1: for n in Favicon.objects.all(): n.isFavicon = False return qs isFavicon = isFavicon[0] return qs.filter(faviconFK=isFavicon) admin.site.register(FaviconImg, FaviconImgAdmin) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1701810659.1261919 django-favicon-plus-reloaded-1.2/favicon/migrations/0000755000175000017500000000000014533710743022231 5ustar00wethjowethjo././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1588607173.0 django-favicon-plus-reloaded-1.2/favicon/migrations/0001_initial.py0000644000175000017500000000255513654034305024677 0ustar00wethjowethjo# -*- coding: utf-8 -*- # Generated by Django 1.9 on 2016-01-02 11:58 from __future__ import unicode_literals from django.db import migrations, models import django.db.models.deletion class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='Favicon', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.CharField(max_length=100)), ('faviconImage', models.ImageField(upload_to='favicon')), ('isFavicon', models.BooleanField(default=True)), ], options={ 'verbose_name_plural': 'Favicons', 'verbose_name': 'Favicon', }, ), migrations.CreateModel( name='FaviconImg', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('size', models.IntegerField()), ('rel', models.CharField(max_length=250, null=True)), ('faviconImage', models.ImageField(upload_to='favicon')), ('faviconFK', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='favicon.Favicon')), ], ), ] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1588607173.0 django-favicon-plus-reloaded-1.2/favicon/migrations/0002_favicon_site.py0000644000175000017500000000123413654034305025711 0ustar00wethjowethjo# Generated by Django 3.0.4 on 2020-04-29 18:02 from django.db import migrations, models import django.db.models.deletion from django.conf import settings use_sites = hasattr(settings, "SITE_ID") class Migration(migrations.Migration): dependencies = [ ('favicon', '0001_initial'), ] if use_sites: dependencies.append(('sites', '0001_initial')) operations = [ migrations.AddField( model_name='favicon', name='site', field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='favicon', to='sites.Site'), ), ] if use_sites else [] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1629904793.0 django-favicon-plus-reloaded-1.2/favicon/migrations/0003_site_manager.py0000644000175000017500000000217714111457631025706 0ustar00wethjowethjo# Generated by Django 3.0.4 on 2020-05-04 16:21 import django.contrib.sites.managers from django.db import migrations, models import django.db.models.deletion import django.db.models.manager from django.conf import settings use_sites = hasattr(settings, "SITE_ID") class Migration(migrations.Migration): dependencies = [ ('favicon', '0002_favicon_site'), ] operations = [ migrations.AlterModelManagers( name='favicon', managers=[ ('objects', django.db.models.manager.Manager()), ('on_site', django.contrib.sites.managers.CurrentSiteManager()), ] if use_sites else [ ('objects', django.db.models.manager.Manager()), ('on_site', django.db.models.manager.Manager()), ], ), ] if use_sites: operations.append( migrations.AlterField( model_name='favicon', name='site', field=models.ForeignKey(blank=True, default=1, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='favicon', to='sites.Site'), ) ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1629904793.0 django-favicon-plus-reloaded-1.2/favicon/migrations/0004_faviconimg_favicon_size_rel_unique.py0000644000175000017500000000065014111457631032354 0ustar00wethjowethjo# Generated by Django 3.2 on 2021-05-15 20:28 from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ('favicon', '0003_site_manager'), ] operations = [ migrations.AddConstraint( model_name='faviconimg', constraint=models.UniqueConstraint(fields=('faviconFK', 'size', 'rel'), name='favicon_size_rel_unique'), ), ] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1588607173.0 django-favicon-plus-reloaded-1.2/favicon/migrations/__init__.py0000644000175000017500000000000113654034305024325 0ustar00wethjowethjo ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1688252385.0 django-favicon-plus-reloaded-1.2/favicon/models.py0000644000175000017500000001174014450127741021713 0ustar00wethjowethjofrom io import BytesIO import sys from PIL import Image from django.conf import settings from django.core.files.storage import default_storage as storage from django.core.files.uploadedfile import InMemoryUploadedFile from django.db import models from django.db.models import Q, signals from django.utils.text import slugify use_sites = hasattr(settings, "SITE_ID") if use_sites: from django.contrib.sites.models import Site from django.contrib.sites.managers import CurrentSiteManager config = { 'shortcut icon': [16, 32, 48, 128, 192], 'touch-icon': [192], 'icon': [192], 'apple-touch-icon': [57, 72, 114, 144, 180], 'apple-touch-icon-precomposed': [57, 72, 76, 114, 120, 144, 152, 180], } config = getattr(settings, 'FAVICON_CONFIG', config) if "shortcut icon" not in config or 32 not in config["shortcut icon"]: config.setdefault("shortcut_icon", []).append(32) image_path = getattr(settings, "FAVICON_PATH", "favicon") def pre_delete_image(sender, instance, **kwargs): instance.del_image() class Favicon(models.Model): title = models.CharField(max_length=100) faviconImage = models.ImageField(upload_to=image_path) isFavicon = models.BooleanField(default=True) objects = models.Manager() on_site = objects if use_sites: site = models.ForeignKey(Site, related_name="favicon", on_delete=models.CASCADE, blank=True, null=True, default=settings.SITE_ID) on_site = CurrentSiteManager() def save(self, *args, **kwargs): self.site = Site.objects.get_current() return super(Favicon, self).save(*args, **kwargs) class Meta: verbose_name = 'Favicon' verbose_name_plural = 'Favicons' def get_favicons(self, update=False, config_override=None): """ Get all combinations of favicons as configured, creating mising ones. Pass update=True to force re-generation of existing icons. """ # Use default config by default if config_override is None: config_override = config # Get all combinations of favicon rels and sizes from config query = Q() for rel in config_override: for size in config_override[rel]: query |= Q(rel=rel, size=size) # Get all existing favicons favicons = FaviconImg.objects.filter(faviconFK=self).filter(query) # Delete all favicon images to update all if update: favicons.delete() favicons = FaviconImg.objects.none() found = [] else: favicons = favicons.all() found = [(f.rel, f.size) for f in favicons] # Check whether favicons are missing new_favicons = [] for rel in config_override: for size in config_override[rel]: if not (rel, size) in found: fav = FaviconImg(faviconFK=self, size=size, rel=rel) fav.generate_image() new_favicons.append(fav) if new_favicons: FaviconImg.objects.bulk_create(new_favicons, ignore_conflicts=True) return list(favicons) + new_favicons def __str__(self): return self.faviconImage.name def get_absolute_url(self): return self.faviconImage.name def del_image(self): self.faviconImage.delete() def as_html(self, update=False): """Return html tags for this favicon set.""" html = '' for favicon in self.get_favicons(update=update): html += favicon.as_html() return html def save(self, *args, **kwargs): if self.isFavicon: Favicon.on_site.exclude(pk=self.pk).update(isFavicon=False) super().save(*args, **kwargs) if self.faviconImage: self.get_favicons(update=True) class FaviconImg(models.Model): faviconFK = models.ForeignKey(Favicon, on_delete=models.CASCADE) size = models.IntegerField() rel = models.CharField(max_length=250, null=True) faviconImage = models.ImageField(upload_to=image_path) def as_html(self): """Return a tag forthis favicon image.""" return f'' def generate_image(self): tmp = Image.open(storage.open(self.faviconFK.faviconImage.name)) tmp.thumbnail((self.size, self.size), Image.LANCZOS) tmp_io = BytesIO() tmp.save(tmp_io, format='PNG') file_name = f"{slugify(self.faviconFK.title)}-{self.size}s.png" tmp_file = InMemoryUploadedFile(tmp_io, None, file_name, 'image/png', sys.getsizeof(tmp_io), None) self.faviconImage = tmp_file def del_image(self): self.faviconImage.delete() class Meta: constraints = [models.UniqueConstraint(fields=["faviconFK", "size", "rel"], name="favicon_size_rel_unique")] signals.pre_delete.connect(pre_delete_image, sender=Favicon) signals.pre_delete.connect(pre_delete_image, sender=FaviconImg) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1701810659.1261919 django-favicon-plus-reloaded-1.2/favicon/templatetags/0000755000175000017500000000000014533710743022547 5ustar00wethjowethjo././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1588607173.0 django-favicon-plus-reloaded-1.2/favicon/templatetags/__init__.py0000644000175000017500000000000013654034305024642 0ustar00wethjowethjo././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1629904793.0 django-favicon-plus-reloaded-1.2/favicon/templatetags/favtags.py0000644000175000017500000000102014111457631024541 0ustar00wethjowethjofrom django import template from django.core.cache import cache from django.utils.safestring import mark_safe from favicon.models import Favicon register = template.Library() @register.simple_tag(takes_context=True) def place_favicon(context): """ Gets Favicon-URL for the Model. Template Syntax: {% place_favicon %} """ fav = Favicon.on_site.filter(isFavicon=True).first() if not fav: return mark_safe('') html = fav.as_html() return mark_safe(html) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1701810458.0 django-favicon-plus-reloaded-1.2/requirements.txt0000644000175000017500000000005214533710432021704 0ustar00wethjowethjodjango>=4.2.0, <6.0 pillow>=10.0.0, <11.0 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1701810659.1261919 django-favicon-plus-reloaded-1.2/setup.cfg0000644000175000017500000000004614533710743020251 0ustar00wethjowethjo[egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1701809114.0 django-favicon-plus-reloaded-1.2/setup.py0000644000175000017500000000310714533705732020145 0ustar00wethjowethjoimport os import sys import codecs import favicon from distutils.core import setup from setuptools import setup, find_packages version = favicon.__version__ setup( name='django-favicon-plus-reloaded', version=version, url='https://edugit.org/AlekSIS/libs/django-favicon-plus', packages=find_packages(), license='MIT', description='Simple Django app which allows you to upload a image and it renders a wide variety for html link tags to display the favicon', long_description=codecs.open('README.md', encoding='utf-8').read(), long_description_content_type='text/markdown', install_requires=open('requirements.txt').read().split('\n'), author='arteria GmbH', author_email='arteria@arteria.ch', maintainer='AlekSIS Team', maintainer_email='aleksis-dev@lists.teckids.org', include_package_data=True, classifiers=[ 'Development Status :: 5 - Production/Stable', 'Environment :: Web Environment', 'Framework :: Django', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', 'Topic :: Internet :: WWW/HTTP', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', ], zip_safe=False )