New upstream version 1.1.3
Dominik George
2 years ago
0 | yannik-ammann | |
1 | bashu | |
2 | Calzzetta | |
3 | philippeowagner | |
4 | walterrenner | |
5 | arthru | |
6 | raphaa | |
7 | Michał Pasternak (mpasternak) | |
8 | ZugBahnHof | |
9 | Natureshadow |
0 | Copyright (c) 2012 arteria GmbH | |
1 | Copyright (c) 2020 Julian Leucker <leuckerj@gmail.com> | |
2 | Copyright (c) 2021 Dominik George <dominik.george@teckids.org> | |
3 | ||
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this | |
5 | software and associated documentation files (the "Software"), to deal in the Software | |
6 | without restriction, including without limitation the rights to use, copy, modify, merge, | |
7 | publish, distribute, sublicense, and/or sell copies of the Software, and to permit | |
8 | persons to whom the Software is furnished to do so, subject to the following conditions: | |
9 | ||
10 | The above copyright notice and this permission notice shall be included in all copies or | |
11 | substantial portions of the Software. | |
12 | ||
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |
14 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | |
15 | PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE | |
16 | FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |
17 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
18 | DEALINGS IN THE SOFTWARE. |
0 | include README.md | |
1 | include LICENSE | |
2 | include requirements.txt | |
3 | recursive-include favicon/templates * | |
4 | recursive-include favicon *.html *.png *.gif *js *.css *jpg *jpeg *svg *py | |
5 | global-exclude *.orig *.pyc *.log *.swp |
0 | Metadata-Version: 2.1 | |
1 | Name: django-favicon-plus-reloaded | |
2 | Version: 1.1.3 | |
3 | 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 | |
4 | Home-page: https://edugit.org/AlekSIS/libs/django-favicon-plus | |
5 | Author: arteria GmbH | |
6 | Author-email: arteria@arteria.ch | |
7 | Maintainer: AlekSIS Team | |
8 | Maintainer-email: aleksis-dev@lists.teckids.org | |
9 | License: MIT | |
10 | Platform: UNKNOWN | |
11 | Classifier: Development Status :: 5 - Production/Stable | |
12 | Classifier: Environment :: Web Environment | |
13 | Classifier: Framework :: Django | |
14 | Classifier: Intended Audience :: Developers | |
15 | Classifier: License :: OSI Approved :: MIT License | |
16 | Classifier: Operating System :: OS Independent | |
17 | Classifier: Programming Language :: Python | |
18 | Classifier: Programming Language :: Python :: 3 | |
19 | Classifier: Programming Language :: Python :: 3.7 | |
20 | Classifier: Programming Language :: Python :: 3.8 | |
21 | Classifier: Topic :: Internet :: WWW/HTTP | |
22 | Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content | |
23 | Description-Content-Type: text/markdown | |
24 | License-File: LICENSE | |
25 | License-File: AUTHORS.txt | |
26 | ||
27 | # django-favicon-plus | |
28 | ||
29 | 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. | |
30 | ||
31 | This version is a fork of the [original version from arteria | |
32 | GmbH](https://github.com/arteria/django-favicon-plus/) due to lack of | |
33 | maintenance. | |
34 | ||
35 | ## How to use: | |
36 | Install django-favicon using PIP. | |
37 | ```shell | |
38 | pip install django-favicon-plus-reloaded | |
39 | pip install git+https://edugit.org/AlekSIS/libs/django-favicon-plus.git | |
40 | ``` | |
41 | ||
42 | Add app to `INSTALLED_APPS` List in your `settings.py` file, make sure `sites`-app is also installed, a URL is | |
43 | specified in the admin backend and you specify your site in settings.py with `SITE_ID = <your-site-id-here>`. | |
44 | ||
45 | ```python | |
46 | INSTALLED_APPS = ( | |
47 | ... | |
48 | 'django.contrib.sites', | |
49 | ... | |
50 | 'favicon', | |
51 | ... | |
52 | ) | |
53 | ``` | |
54 | The default `FAVICON_CONFIG` look like this, if you want something else you can define it in your settings.py. | |
55 | The key of the dictionary is the value for the `rel` attribute of the link tag, while the list in the value are the | |
56 | sizes for the `size` attribute and the image resizing. | |
57 | ||
58 | ```python | |
59 | FAVICON_CONFIG = { | |
60 | 'shortcut icon': [16 ,32 ,48 ,128, 192], | |
61 | 'touch-icon': [196], | |
62 | 'icon': [196], | |
63 | 'apple-touch-icon': [57, 72, 114, 144, 180], | |
64 | 'apple-touch-icon-precomposed': [57, 72, 76, 114, 120, 144, 152,180], | |
65 | } | |
66 | ``` | |
67 | Please make sure you have specified a `MEDIA_URL` in `settings.py` and your root `urlconf` looks like this: | |
68 | ||
69 | ```python | |
70 | urlpatterns = [ | |
71 | path('admin/', admin.site.urls), | |
72 | ..., | |
73 | ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) | |
74 | ``` | |
75 | ||
76 | You can also provide a `FAVICON_PATH` in your `settings.py` to specify the folder name of your favicon folder. | |
77 | The default is `favicon` | |
78 | ||
79 | Upload an image in the admin backend --> all the size will be created, its best to take a larger base favicon. | |
80 | ||
81 | Use the templatetag in your base.html | |
82 | ```html+django | |
83 | {% load favtags %} | |
84 | ||
85 | {% place_favicon %} | |
86 | ``` | |
87 | this will create: | |
88 | ```html | |
89 | <link rel="apple-touch-icon-precomposed" size ="180x180" href="/media/favicon/fav-180.png"/> | |
90 | <link rel="apple-touch-icon-precomposed" size ="152x152" href="/media/favicon/fav-152.png"/> | |
91 | <link rel="apple-touch-icon-precomposed" size ="144x144" href="/media/favicon/fav-144.png"/> | |
92 | <link rel="apple-touch-icon-precomposed" size ="120x120" href="/media/favicon/fav-120.png"/> | |
93 | <link rel="apple-touch-icon-precomposed" size ="114x114" href="/media/favicon/fav-114.png"/> | |
94 | <link rel="apple-touch-icon-precomposed" size ="76x76" href="/media/favicon/fav-76.png"/> | |
95 | <link rel="apple-touch-icon-precomposed" size ="72x72" href="/media/favicon/fav-72.png"/> | |
96 | <link rel="apple-touch-icon-precomposed" size ="57x57" href="/media/favicon/fav-57.png"/> | |
97 | <link rel="apple-touch-icon" size ="180x180" href="/media/favicon/fav-180_5l5PyO1.png"/> | |
98 | <link rel="apple-touch-icon" size ="144x144" href="/media/favicon/fav-144_5A8THfC.png"/> | |
99 | <link rel="apple-touch-icon" size ="114x114" href="/media/favicon/fav-114_GqBGFXA.png"/> | |
100 | <link rel="apple-touch-icon" size ="72x72" href="/media/favicon/fav-72_UoWu9ik.png"/> | |
101 | <link rel="apple-touch-icon" size ="57x57" href="/media/favicon/fav-57_sfX3XoJ.png"/> | |
102 | <link rel="touch-icon" size ="192x192" href="/media/favicon/fav-192.png"/> | |
103 | <link rel="shortcut icon" size ="192x192" href="/media/favicon/fav-192_rD0bCKr.png"/> | |
104 | <link rel="shortcut icon" size ="128x128" href="/media/favicon/fav-128.png"/> | |
105 | <link rel="shortcut icon" size ="48x48" href="/media/favicon/fav-48.png"/> | |
106 | <link rel="shortcut icon" size ="32x32" href="/media/favicon/fav-32.png"/> | |
107 | <link rel="shortcut icon" size ="16x16" href="/media/favicon/fav-16.png"/> | |
108 | <link rel="icon" size ="192x192" href="/media/favicon/fav-192_Gw5Uu1M.png"/> | |
109 | <link rel="shortcut icon" size ="32x32" href="/media/favicon/fav-32.png"/> | |
110 | ``` | |
111 | ## Management | |
112 | ||
113 | You can upload multiple images, but only one is set as favicon and used. | |
114 | ||
115 | ||
116 | ## Contribution | |
117 | ||
118 | If you want to contribute something send an MR. | |
119 | ||
120 | ||
121 | # Source | |
122 | ||
123 | ### Based on | |
124 | ||
125 | [Favicon Cheat Sheet on github](https://github.com/audreyr/favicon-cheat-sheet) | |
126 | ||
127 | ### Favicon | |
128 | 16x16 .ico or better .png | |
129 | ```html | |
130 | <link rel="shortcut icon" href="/images/favicon.png" /> | |
131 | ``` | |
132 | ### apple-touch-icon(-precomposed) | |
133 | 57x57, 72x72, 114x114, and 144x144 | |
134 | highest resolution for ipad retina 144x144.png precomposed(=iOS won’t add any effects to the icon) | |
135 | ```html | |
136 | <link rel="apple-touch-icon" sizes="144x144" href="/images/apple-touch-icon-144x144.png"> | |
137 | <link rel="apple-touch-icon" sizes="114x114" href="/images/apple-touch-icon-114x114.png"> | |
138 | <link rel="apple-touch-icon" sizes="72x72" href="/images/apple-touch-icon-72x72.png"> | |
139 | <link rel="apple-touch-icon" sizes="57x57" href="/images/apple-touch-icon-57x57.png"> | |
140 | ||
141 | <link rel="apple-touch-icon-precomposed" sizes="144x144" href="/images/apple-touch-icon-144x144.png"> | |
142 | <link rel="apple-touch-icon-precomposed" sizes="114x114" href="/images/apple-touch-icon-114x114.png"> | |
143 | <link rel="apple-touch-icon-precomposed" sizes="72x72" href="/images/apple-touch-icon-72x72.png"> | |
144 | <link rel="apple-touch-icon-precomposed" sizes="57x57" href="/images/apple-touch-icon-57x57.png"> | |
145 | ``` | |
146 | 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. | |
147 | ||
148 | 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. | |
149 | ||
150 | https://mathiasbynens.be/notes/touch-icons | |
151 | ||
152 |
0 | # django-favicon-plus | |
1 | ||
2 | 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. | |
3 | ||
4 | This version is a fork of the [original version from arteria | |
5 | GmbH](https://github.com/arteria/django-favicon-plus/) due to lack of | |
6 | maintenance. | |
7 | ||
8 | ## How to use: | |
9 | Install django-favicon using PIP. | |
10 | ```shell | |
11 | pip install django-favicon-plus-reloaded | |
12 | pip install git+https://edugit.org/AlekSIS/libs/django-favicon-plus.git | |
13 | ``` | |
14 | ||
15 | Add app to `INSTALLED_APPS` List in your `settings.py` file, make sure `sites`-app is also installed, a URL is | |
16 | specified in the admin backend and you specify your site in settings.py with `SITE_ID = <your-site-id-here>`. | |
17 | ||
18 | ```python | |
19 | INSTALLED_APPS = ( | |
20 | ... | |
21 | 'django.contrib.sites', | |
22 | ... | |
23 | 'favicon', | |
24 | ... | |
25 | ) | |
26 | ``` | |
27 | The default `FAVICON_CONFIG` look like this, if you want something else you can define it in your settings.py. | |
28 | The key of the dictionary is the value for the `rel` attribute of the link tag, while the list in the value are the | |
29 | sizes for the `size` attribute and the image resizing. | |
30 | ||
31 | ```python | |
32 | FAVICON_CONFIG = { | |
33 | 'shortcut icon': [16 ,32 ,48 ,128, 192], | |
34 | 'touch-icon': [196], | |
35 | 'icon': [196], | |
36 | 'apple-touch-icon': [57, 72, 114, 144, 180], | |
37 | 'apple-touch-icon-precomposed': [57, 72, 76, 114, 120, 144, 152,180], | |
38 | } | |
39 | ``` | |
40 | Please make sure you have specified a `MEDIA_URL` in `settings.py` and your root `urlconf` looks like this: | |
41 | ||
42 | ```python | |
43 | urlpatterns = [ | |
44 | path('admin/', admin.site.urls), | |
45 | ..., | |
46 | ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) | |
47 | ``` | |
48 | ||
49 | You can also provide a `FAVICON_PATH` in your `settings.py` to specify the folder name of your favicon folder. | |
50 | The default is `favicon` | |
51 | ||
52 | Upload an image in the admin backend --> all the size will be created, its best to take a larger base favicon. | |
53 | ||
54 | Use the templatetag in your base.html | |
55 | ```html+django | |
56 | {% load favtags %} | |
57 | ||
58 | {% place_favicon %} | |
59 | ``` | |
60 | this will create: | |
61 | ```html | |
62 | <link rel="apple-touch-icon-precomposed" size ="180x180" href="/media/favicon/fav-180.png"/> | |
63 | <link rel="apple-touch-icon-precomposed" size ="152x152" href="/media/favicon/fav-152.png"/> | |
64 | <link rel="apple-touch-icon-precomposed" size ="144x144" href="/media/favicon/fav-144.png"/> | |
65 | <link rel="apple-touch-icon-precomposed" size ="120x120" href="/media/favicon/fav-120.png"/> | |
66 | <link rel="apple-touch-icon-precomposed" size ="114x114" href="/media/favicon/fav-114.png"/> | |
67 | <link rel="apple-touch-icon-precomposed" size ="76x76" href="/media/favicon/fav-76.png"/> | |
68 | <link rel="apple-touch-icon-precomposed" size ="72x72" href="/media/favicon/fav-72.png"/> | |
69 | <link rel="apple-touch-icon-precomposed" size ="57x57" href="/media/favicon/fav-57.png"/> | |
70 | <link rel="apple-touch-icon" size ="180x180" href="/media/favicon/fav-180_5l5PyO1.png"/> | |
71 | <link rel="apple-touch-icon" size ="144x144" href="/media/favicon/fav-144_5A8THfC.png"/> | |
72 | <link rel="apple-touch-icon" size ="114x114" href="/media/favicon/fav-114_GqBGFXA.png"/> | |
73 | <link rel="apple-touch-icon" size ="72x72" href="/media/favicon/fav-72_UoWu9ik.png"/> | |
74 | <link rel="apple-touch-icon" size ="57x57" href="/media/favicon/fav-57_sfX3XoJ.png"/> | |
75 | <link rel="touch-icon" size ="192x192" href="/media/favicon/fav-192.png"/> | |
76 | <link rel="shortcut icon" size ="192x192" href="/media/favicon/fav-192_rD0bCKr.png"/> | |
77 | <link rel="shortcut icon" size ="128x128" href="/media/favicon/fav-128.png"/> | |
78 | <link rel="shortcut icon" size ="48x48" href="/media/favicon/fav-48.png"/> | |
79 | <link rel="shortcut icon" size ="32x32" href="/media/favicon/fav-32.png"/> | |
80 | <link rel="shortcut icon" size ="16x16" href="/media/favicon/fav-16.png"/> | |
81 | <link rel="icon" size ="192x192" href="/media/favicon/fav-192_Gw5Uu1M.png"/> | |
82 | <link rel="shortcut icon" size ="32x32" href="/media/favicon/fav-32.png"/> | |
83 | ``` | |
84 | ## Management | |
85 | ||
86 | You can upload multiple images, but only one is set as favicon and used. | |
87 | ||
88 | ||
89 | ## Contribution | |
90 | ||
91 | If you want to contribute something send an MR. | |
92 | ||
93 | ||
94 | # Source | |
95 | ||
96 | ### Based on | |
97 | ||
98 | [Favicon Cheat Sheet on github](https://github.com/audreyr/favicon-cheat-sheet) | |
99 | ||
100 | ### Favicon | |
101 | 16x16 .ico or better .png | |
102 | ```html | |
103 | <link rel="shortcut icon" href="/images/favicon.png" /> | |
104 | ``` | |
105 | ### apple-touch-icon(-precomposed) | |
106 | 57x57, 72x72, 114x114, and 144x144 | |
107 | highest resolution for ipad retina 144x144.png precomposed(=iOS won’t add any effects to the icon) | |
108 | ```html | |
109 | <link rel="apple-touch-icon" sizes="144x144" href="/images/apple-touch-icon-144x144.png"> | |
110 | <link rel="apple-touch-icon" sizes="114x114" href="/images/apple-touch-icon-114x114.png"> | |
111 | <link rel="apple-touch-icon" sizes="72x72" href="/images/apple-touch-icon-72x72.png"> | |
112 | <link rel="apple-touch-icon" sizes="57x57" href="/images/apple-touch-icon-57x57.png"> | |
113 | ||
114 | <link rel="apple-touch-icon-precomposed" sizes="144x144" href="/images/apple-touch-icon-144x144.png"> | |
115 | <link rel="apple-touch-icon-precomposed" sizes="114x114" href="/images/apple-touch-icon-114x114.png"> | |
116 | <link rel="apple-touch-icon-precomposed" sizes="72x72" href="/images/apple-touch-icon-72x72.png"> | |
117 | <link rel="apple-touch-icon-precomposed" sizes="57x57" href="/images/apple-touch-icon-57x57.png"> | |
118 | ``` | |
119 | 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. | |
120 | ||
121 | 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. | |
122 | ||
123 | https://mathiasbynens.be/notes/touch-icons |
0 | Metadata-Version: 2.1 | |
1 | Name: django-favicon-plus-reloaded | |
2 | Version: 1.1.3 | |
3 | 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 | |
4 | Home-page: https://edugit.org/AlekSIS/libs/django-favicon-plus | |
5 | Author: arteria GmbH | |
6 | Author-email: arteria@arteria.ch | |
7 | Maintainer: AlekSIS Team | |
8 | Maintainer-email: aleksis-dev@lists.teckids.org | |
9 | License: MIT | |
10 | Platform: UNKNOWN | |
11 | Classifier: Development Status :: 5 - Production/Stable | |
12 | Classifier: Environment :: Web Environment | |
13 | Classifier: Framework :: Django | |
14 | Classifier: Intended Audience :: Developers | |
15 | Classifier: License :: OSI Approved :: MIT License | |
16 | Classifier: Operating System :: OS Independent | |
17 | Classifier: Programming Language :: Python | |
18 | Classifier: Programming Language :: Python :: 3 | |
19 | Classifier: Programming Language :: Python :: 3.7 | |
20 | Classifier: Programming Language :: Python :: 3.8 | |
21 | Classifier: Topic :: Internet :: WWW/HTTP | |
22 | Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content | |
23 | Description-Content-Type: text/markdown | |
24 | License-File: LICENSE | |
25 | License-File: AUTHORS.txt | |
26 | ||
27 | # django-favicon-plus | |
28 | ||
29 | 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. | |
30 | ||
31 | This version is a fork of the [original version from arteria | |
32 | GmbH](https://github.com/arteria/django-favicon-plus/) due to lack of | |
33 | maintenance. | |
34 | ||
35 | ## How to use: | |
36 | Install django-favicon using PIP. | |
37 | ```shell | |
38 | pip install django-favicon-plus-reloaded | |
39 | pip install git+https://edugit.org/AlekSIS/libs/django-favicon-plus.git | |
40 | ``` | |
41 | ||
42 | Add app to `INSTALLED_APPS` List in your `settings.py` file, make sure `sites`-app is also installed, a URL is | |
43 | specified in the admin backend and you specify your site in settings.py with `SITE_ID = <your-site-id-here>`. | |
44 | ||
45 | ```python | |
46 | INSTALLED_APPS = ( | |
47 | ... | |
48 | 'django.contrib.sites', | |
49 | ... | |
50 | 'favicon', | |
51 | ... | |
52 | ) | |
53 | ``` | |
54 | The default `FAVICON_CONFIG` look like this, if you want something else you can define it in your settings.py. | |
55 | The key of the dictionary is the value for the `rel` attribute of the link tag, while the list in the value are the | |
56 | sizes for the `size` attribute and the image resizing. | |
57 | ||
58 | ```python | |
59 | FAVICON_CONFIG = { | |
60 | 'shortcut icon': [16 ,32 ,48 ,128, 192], | |
61 | 'touch-icon': [196], | |
62 | 'icon': [196], | |
63 | 'apple-touch-icon': [57, 72, 114, 144, 180], | |
64 | 'apple-touch-icon-precomposed': [57, 72, 76, 114, 120, 144, 152,180], | |
65 | } | |
66 | ``` | |
67 | Please make sure you have specified a `MEDIA_URL` in `settings.py` and your root `urlconf` looks like this: | |
68 | ||
69 | ```python | |
70 | urlpatterns = [ | |
71 | path('admin/', admin.site.urls), | |
72 | ..., | |
73 | ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) | |
74 | ``` | |
75 | ||
76 | You can also provide a `FAVICON_PATH` in your `settings.py` to specify the folder name of your favicon folder. | |
77 | The default is `favicon` | |
78 | ||
79 | Upload an image in the admin backend --> all the size will be created, its best to take a larger base favicon. | |
80 | ||
81 | Use the templatetag in your base.html | |
82 | ```html+django | |
83 | {% load favtags %} | |
84 | ||
85 | {% place_favicon %} | |
86 | ``` | |
87 | this will create: | |
88 | ```html | |
89 | <link rel="apple-touch-icon-precomposed" size ="180x180" href="/media/favicon/fav-180.png"/> | |
90 | <link rel="apple-touch-icon-precomposed" size ="152x152" href="/media/favicon/fav-152.png"/> | |
91 | <link rel="apple-touch-icon-precomposed" size ="144x144" href="/media/favicon/fav-144.png"/> | |
92 | <link rel="apple-touch-icon-precomposed" size ="120x120" href="/media/favicon/fav-120.png"/> | |
93 | <link rel="apple-touch-icon-precomposed" size ="114x114" href="/media/favicon/fav-114.png"/> | |
94 | <link rel="apple-touch-icon-precomposed" size ="76x76" href="/media/favicon/fav-76.png"/> | |
95 | <link rel="apple-touch-icon-precomposed" size ="72x72" href="/media/favicon/fav-72.png"/> | |
96 | <link rel="apple-touch-icon-precomposed" size ="57x57" href="/media/favicon/fav-57.png"/> | |
97 | <link rel="apple-touch-icon" size ="180x180" href="/media/favicon/fav-180_5l5PyO1.png"/> | |
98 | <link rel="apple-touch-icon" size ="144x144" href="/media/favicon/fav-144_5A8THfC.png"/> | |
99 | <link rel="apple-touch-icon" size ="114x114" href="/media/favicon/fav-114_GqBGFXA.png"/> | |
100 | <link rel="apple-touch-icon" size ="72x72" href="/media/favicon/fav-72_UoWu9ik.png"/> | |
101 | <link rel="apple-touch-icon" size ="57x57" href="/media/favicon/fav-57_sfX3XoJ.png"/> | |
102 | <link rel="touch-icon" size ="192x192" href="/media/favicon/fav-192.png"/> | |
103 | <link rel="shortcut icon" size ="192x192" href="/media/favicon/fav-192_rD0bCKr.png"/> | |
104 | <link rel="shortcut icon" size ="128x128" href="/media/favicon/fav-128.png"/> | |
105 | <link rel="shortcut icon" size ="48x48" href="/media/favicon/fav-48.png"/> | |
106 | <link rel="shortcut icon" size ="32x32" href="/media/favicon/fav-32.png"/> | |
107 | <link rel="shortcut icon" size ="16x16" href="/media/favicon/fav-16.png"/> | |
108 | <link rel="icon" size ="192x192" href="/media/favicon/fav-192_Gw5Uu1M.png"/> | |
109 | <link rel="shortcut icon" size ="32x32" href="/media/favicon/fav-32.png"/> | |
110 | ``` | |
111 | ## Management | |
112 | ||
113 | You can upload multiple images, but only one is set as favicon and used. | |
114 | ||
115 | ||
116 | ## Contribution | |
117 | ||
118 | If you want to contribute something send an MR. | |
119 | ||
120 | ||
121 | # Source | |
122 | ||
123 | ### Based on | |
124 | ||
125 | [Favicon Cheat Sheet on github](https://github.com/audreyr/favicon-cheat-sheet) | |
126 | ||
127 | ### Favicon | |
128 | 16x16 .ico or better .png | |
129 | ```html | |
130 | <link rel="shortcut icon" href="/images/favicon.png" /> | |
131 | ``` | |
132 | ### apple-touch-icon(-precomposed) | |
133 | 57x57, 72x72, 114x114, and 144x144 | |
134 | highest resolution for ipad retina 144x144.png precomposed(=iOS won’t add any effects to the icon) | |
135 | ```html | |
136 | <link rel="apple-touch-icon" sizes="144x144" href="/images/apple-touch-icon-144x144.png"> | |
137 | <link rel="apple-touch-icon" sizes="114x114" href="/images/apple-touch-icon-114x114.png"> | |
138 | <link rel="apple-touch-icon" sizes="72x72" href="/images/apple-touch-icon-72x72.png"> | |
139 | <link rel="apple-touch-icon" sizes="57x57" href="/images/apple-touch-icon-57x57.png"> | |
140 | ||
141 | <link rel="apple-touch-icon-precomposed" sizes="144x144" href="/images/apple-touch-icon-144x144.png"> | |
142 | <link rel="apple-touch-icon-precomposed" sizes="114x114" href="/images/apple-touch-icon-114x114.png"> | |
143 | <link rel="apple-touch-icon-precomposed" sizes="72x72" href="/images/apple-touch-icon-72x72.png"> | |
144 | <link rel="apple-touch-icon-precomposed" sizes="57x57" href="/images/apple-touch-icon-57x57.png"> | |
145 | ``` | |
146 | 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. | |
147 | ||
148 | 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. | |
149 | ||
150 | https://mathiasbynens.be/notes/touch-icons | |
151 | ||
152 |
0 | AUTHORS.txt | |
1 | LICENSE | |
2 | MANIFEST.in | |
3 | README.md | |
4 | requirements.txt | |
5 | setup.py | |
6 | django_favicon_plus_reloaded.egg-info/PKG-INFO | |
7 | django_favicon_plus_reloaded.egg-info/SOURCES.txt | |
8 | django_favicon_plus_reloaded.egg-info/dependency_links.txt | |
9 | django_favicon_plus_reloaded.egg-info/not-zip-safe | |
10 | django_favicon_plus_reloaded.egg-info/requires.txt | |
11 | django_favicon_plus_reloaded.egg-info/top_level.txt | |
12 | favicon/__init__.py | |
13 | favicon/admin.py | |
14 | favicon/models.py | |
15 | favicon/migrations/0001_initial.py | |
16 | favicon/migrations/0002_favicon_site.py | |
17 | favicon/migrations/0003_site_manager.py | |
18 | favicon/migrations/0004_faviconimg_favicon_size_rel_unique.py | |
19 | favicon/migrations/__init__.py | |
20 | favicon/templatetags/__init__.py | |
21 | favicon/templatetags/favtags.py⏎ |
0 | favicon |
0 | __version__ = '1.1.3' |
0 | from django.contrib import admin | |
1 | from favicon.models import Favicon, FaviconImg | |
2 | ||
3 | ||
4 | class FaviconAdmin(admin.ModelAdmin): | |
5 | list_display = ('title', 'isFavicon') | |
6 | ||
7 | ||
8 | admin.site.register(Favicon, FaviconAdmin) | |
9 | ||
10 | ||
11 | class FaviconImgAdmin(admin.ModelAdmin): | |
12 | list_display = ('faviconFK', 'rel', 'size', 'faviconImage') | |
13 | ||
14 | def queryset(self, request): | |
15 | qs = super(FaviconImgAdmin, self).queryset(request) | |
16 | isFavicon = Favicon.objects.filter(isFavicon=True) | |
17 | if not len(isFavicon) == 1: | |
18 | for n in Favicon.objects.all(): | |
19 | n.isFavicon = False | |
20 | return qs | |
21 | isFavicon = isFavicon[0] | |
22 | return qs.filter(faviconFK=isFavicon) | |
23 | ||
24 | ||
25 | admin.site.register(FaviconImg, FaviconImgAdmin) |
0 | # -*- coding: utf-8 -*- | |
1 | # Generated by Django 1.9 on 2016-01-02 11:58 | |
2 | from __future__ import unicode_literals | |
3 | ||
4 | from django.db import migrations, models | |
5 | import django.db.models.deletion | |
6 | ||
7 | ||
8 | class Migration(migrations.Migration): | |
9 | ||
10 | initial = True | |
11 | ||
12 | dependencies = [ | |
13 | ] | |
14 | ||
15 | operations = [ | |
16 | migrations.CreateModel( | |
17 | name='Favicon', | |
18 | fields=[ | |
19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |
20 | ('title', models.CharField(max_length=100)), | |
21 | ('faviconImage', models.ImageField(upload_to='favicon')), | |
22 | ('isFavicon', models.BooleanField(default=True)), | |
23 | ], | |
24 | options={ | |
25 | 'verbose_name_plural': 'Favicons', | |
26 | 'verbose_name': 'Favicon', | |
27 | }, | |
28 | ), | |
29 | migrations.CreateModel( | |
30 | name='FaviconImg', | |
31 | fields=[ | |
32 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |
33 | ('size', models.IntegerField()), | |
34 | ('rel', models.CharField(max_length=250, null=True)), | |
35 | ('faviconImage', models.ImageField(upload_to='favicon')), | |
36 | ('faviconFK', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='favicon.Favicon')), | |
37 | ], | |
38 | ), | |
39 | ] |
0 | # Generated by Django 3.0.4 on 2020-04-29 18:02 | |
1 | ||
2 | from django.db import migrations, models | |
3 | import django.db.models.deletion | |
4 | from django.conf import settings | |
5 | ||
6 | use_sites = hasattr(settings, "SITE_ID") | |
7 | ||
8 | ||
9 | class Migration(migrations.Migration): | |
10 | dependencies = [ | |
11 | ('favicon', '0001_initial'), | |
12 | ] | |
13 | if use_sites: | |
14 | dependencies.append(('sites', '0001_initial')) | |
15 | ||
16 | operations = [ | |
17 | migrations.AddField( | |
18 | model_name='favicon', | |
19 | name='site', | |
20 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='favicon', to='sites.Site'), | |
21 | ), | |
22 | ] if use_sites else [] |
0 | # Generated by Django 3.0.4 on 2020-05-04 16:21 | |
1 | ||
2 | import django.contrib.sites.managers | |
3 | from django.db import migrations, models | |
4 | import django.db.models.deletion | |
5 | import django.db.models.manager | |
6 | from django.conf import settings | |
7 | ||
8 | ||
9 | use_sites = hasattr(settings, "SITE_ID") | |
10 | ||
11 | ||
12 | class Migration(migrations.Migration): | |
13 | ||
14 | dependencies = [ | |
15 | ('favicon', '0002_favicon_site'), | |
16 | ] | |
17 | ||
18 | operations = [ | |
19 | migrations.AlterModelManagers( | |
20 | name='favicon', | |
21 | managers=[ | |
22 | ('objects', django.db.models.manager.Manager()), | |
23 | ('on_site', django.contrib.sites.managers.CurrentSiteManager()), | |
24 | ] if use_sites else [ | |
25 | ('objects', django.db.models.manager.Manager()), | |
26 | ('on_site', django.db.models.manager.Manager()), | |
27 | ], | |
28 | ), | |
29 | ] | |
30 | if use_sites: | |
31 | operations.append( | |
32 | migrations.AlterField( | |
33 | model_name='favicon', | |
34 | name='site', | |
35 | field=models.ForeignKey(blank=True, default=1, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='favicon', to='sites.Site'), | |
36 | ) | |
37 | ) |
0 | # Generated by Django 3.2 on 2021-05-15 20:28 | |
1 | ||
2 | from django.db import migrations, models | |
3 | ||
4 | ||
5 | class Migration(migrations.Migration): | |
6 | ||
7 | dependencies = [ | |
8 | ('favicon', '0003_site_manager'), | |
9 | ] | |
10 | ||
11 | operations = [ | |
12 | migrations.AddConstraint( | |
13 | model_name='faviconimg', | |
14 | constraint=models.UniqueConstraint(fields=('faviconFK', 'size', 'rel'), name='favicon_size_rel_unique'), | |
15 | ), | |
16 | ] |
0 | from io import BytesIO | |
1 | import sys | |
2 | ||
3 | from PIL import Image | |
4 | from django.conf import settings | |
5 | from django.core.files.storage import default_storage as storage | |
6 | from django.core.files.uploadedfile import InMemoryUploadedFile | |
7 | from django.db import models | |
8 | from django.db.models import Q, signals | |
9 | ||
10 | use_sites = hasattr(settings, "SITE_ID") | |
11 | ||
12 | if use_sites: | |
13 | from django.contrib.sites.models import Site | |
14 | from django.contrib.sites.managers import CurrentSiteManager | |
15 | ||
16 | config = { | |
17 | 'shortcut icon': [16, 32, 48, 128, 192], | |
18 | 'touch-icon': [192], | |
19 | 'icon': [192], | |
20 | 'apple-touch-icon': [57, 72, 114, 144, 180], | |
21 | 'apple-touch-icon-precomposed': [57, 72, 76, 114, 120, 144, 152, 180], | |
22 | } | |
23 | ||
24 | config = getattr(settings, 'FAVICON_CONFIG', config) | |
25 | if "shortcut icon" not in config or 32 not in config["shortcut icon"]: | |
26 | config.setdefault("shortcut_icon", []).append(32) | |
27 | ||
28 | ||
29 | image_path = getattr(settings, "FAVICON_PATH", "favicon") | |
30 | ||
31 | ||
32 | def pre_delete_image(sender, instance, **kwargs): | |
33 | instance.del_image() | |
34 | ||
35 | ||
36 | class Favicon(models.Model): | |
37 | title = models.CharField(max_length=100) | |
38 | faviconImage = models.ImageField(upload_to=image_path) | |
39 | ||
40 | isFavicon = models.BooleanField(default=True) | |
41 | ||
42 | objects = models.Manager() | |
43 | on_site = objects | |
44 | ||
45 | if use_sites: | |
46 | site = models.ForeignKey(Site, related_name="favicon", on_delete=models.CASCADE, blank=True, null=True, default=settings.SITE_ID) | |
47 | ||
48 | on_site = CurrentSiteManager() | |
49 | ||
50 | def save(self, *args, **kwargs): | |
51 | self.site = Site.objects.get_current() | |
52 | return super(Favicon, self).save(*args, **kwargs) | |
53 | ||
54 | class Meta: | |
55 | verbose_name = 'Favicon' | |
56 | verbose_name_plural = 'Favicons' | |
57 | ||
58 | def get_favicons(self, update=False, config_override=None): | |
59 | """ | |
60 | Get all combinations of favicons as configured, creating mising ones. | |
61 | ||
62 | Pass update=True to force re-generation of existing icons. | |
63 | """ | |
64 | # Use default config by default | |
65 | if config_override is None: | |
66 | config_override = config | |
67 | # Get all combinations of favicon rels and sizes from config | |
68 | query = Q() | |
69 | for rel in config_override: | |
70 | for size in config_override[rel]: | |
71 | query |= Q(rel=rel, size=size) | |
72 | ||
73 | # Get all existing favicons | |
74 | favicons = FaviconImg.objects.filter(faviconFK=self).filter(query) | |
75 | ||
76 | # Delete all favicon images to update all | |
77 | if update: | |
78 | favicons.delete() | |
79 | favicons = FaviconImg.objects.none() | |
80 | found = [] | |
81 | else: | |
82 | favicons = favicons.all() | |
83 | found = [(f.rel, f.size) for f in favicons] | |
84 | ||
85 | # Check whether favicons are missing | |
86 | new_favicons = [] | |
87 | for rel in config_override: | |
88 | for size in config_override[rel]: | |
89 | if not (rel, size) in found: | |
90 | fav = FaviconImg(faviconFK=self, size=size, rel=rel) | |
91 | fav.generate_image() | |
92 | new_favicons.append(fav) | |
93 | if new_favicons: | |
94 | FaviconImg.objects.bulk_create(new_favicons, ignore_conflicts=True) | |
95 | ||
96 | return list(favicons) + new_favicons | |
97 | ||
98 | def __str__(self): | |
99 | return self.faviconImage.name | |
100 | ||
101 | def get_absolute_url(self): | |
102 | return self.faviconImage.name | |
103 | ||
104 | def del_image(self): | |
105 | self.faviconImage.delete() | |
106 | ||
107 | def as_html(self, update=False): | |
108 | """Return <link> html tags for this favicon set.""" | |
109 | html = '' | |
110 | for favicon in self.get_favicons(update=update): | |
111 | html += favicon.as_html() | |
112 | return html | |
113 | ||
114 | def save(self, *args, **kwargs): | |
115 | if self.isFavicon: | |
116 | Favicon.on_site.exclude(pk=self.pk).update(isFavicon=False) | |
117 | ||
118 | super().save(*args, **kwargs) | |
119 | ||
120 | if self.faviconImage: | |
121 | self.get_favicons(update=True) | |
122 | ||
123 | ||
124 | class FaviconImg(models.Model): | |
125 | faviconFK = models.ForeignKey(Favicon, on_delete=models.CASCADE) | |
126 | size = models.IntegerField() | |
127 | rel = models.CharField(max_length=250, null=True) | |
128 | faviconImage = models.ImageField(upload_to=image_path) | |
129 | ||
130 | def as_html(self): | |
131 | """Return a <link> tag forthis favicon image.""" | |
132 | return f'<link rel="{self.rel}" sizes="{self.size}x{self.size}" href="{self.faviconImage.url}"/>' | |
133 | ||
134 | def generate_image(self): | |
135 | tmp = Image.open(storage.open(self.faviconFK.faviconImage.name)) | |
136 | tmp.thumbnail((self.size, self.size), Image.ANTIALIAS) | |
137 | ||
138 | tmp_io = BytesIO() | |
139 | tmp.save(tmp_io, format='PNG') | |
140 | tmp_file = InMemoryUploadedFile(tmp_io, None, f"fav-{self.size}s.png", 'image/png', sys.getsizeof(tmp_io), None) | |
141 | ||
142 | self.faviconImage = tmp_file | |
143 | ||
144 | def del_image(self): | |
145 | self.faviconImage.delete() | |
146 | ||
147 | class Meta: | |
148 | constraints = [models.UniqueConstraint(fields=["faviconFK", "size", "rel"], name="favicon_size_rel_unique")] | |
149 | ||
150 | ||
151 | signals.pre_delete.connect(pre_delete_image, sender=Favicon) | |
152 | signals.pre_delete.connect(pre_delete_image, sender=FaviconImg) |
0 | from django import template | |
1 | from django.core.cache import cache | |
2 | from django.utils.safestring import mark_safe | |
3 | ||
4 | from favicon.models import Favicon | |
5 | ||
6 | register = template.Library() | |
7 | ||
8 | ||
9 | @register.simple_tag(takes_context=True) | |
10 | def place_favicon(context): | |
11 | """ | |
12 | Gets Favicon-URL for the Model. | |
13 | ||
14 | Template Syntax: | |
15 | ||
16 | {% place_favicon %} | |
17 | ||
18 | """ | |
19 | ||
20 | fav = Favicon.on_site.filter(isFavicon=True).first() | |
21 | if not fav: | |
22 | return mark_safe('<!-- no favicon -->') | |
23 | ||
24 | html = fav.as_html() | |
25 | return mark_safe(html) |
0 | import os | |
1 | import sys | |
2 | import codecs | |
3 | import favicon | |
4 | ||
5 | from distutils.core import setup | |
6 | from setuptools import setup, find_packages | |
7 | ||
8 | version = favicon.__version__ | |
9 | ||
10 | setup( | |
11 | name='django-favicon-plus-reloaded', | |
12 | version=version, | |
13 | url='https://edugit.org/AlekSIS/libs/django-favicon-plus', | |
14 | packages=find_packages(), | |
15 | license='MIT', | |
16 | 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', | |
17 | long_description=codecs.open('README.md', encoding='utf-8').read(), | |
18 | long_description_content_type='text/markdown', | |
19 | install_requires=open('requirements.txt').read().split('\n'), | |
20 | author='arteria GmbH', | |
21 | author_email='arteria@arteria.ch', | |
22 | maintainer='AlekSIS Team', | |
23 | maintainer_email='aleksis-dev@lists.teckids.org', | |
24 | include_package_data=True, | |
25 | classifiers=[ | |
26 | 'Development Status :: 5 - Production/Stable', | |
27 | 'Environment :: Web Environment', | |
28 | 'Framework :: Django', | |
29 | 'Intended Audience :: Developers', | |
30 | 'License :: OSI Approved :: MIT License', | |
31 | 'Operating System :: OS Independent', | |
32 | 'Programming Language :: Python', | |
33 | 'Programming Language :: Python :: 3', | |
34 | 'Programming Language :: Python :: 3.7', | |
35 | 'Programming Language :: Python :: 3.8', | |
36 | 'Topic :: Internet :: WWW/HTTP', | |
37 | 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', | |
38 | ], | |
39 | zip_safe=False | |
40 | ) |