Compare commits

..

5 Commits

Author SHA1 Message Date
lavirez
fdff0811a1 cli.py missing f string (#877) 2023-11-10 15:09:22 +02:00
Kyle Maas
92c0ff579a Add sitemap (#572)
add sitemap.xml
2023-11-10 15:03:36 +02:00
Markos Gogoulos
847cff2b5c license section 2023-11-10 14:30:14 +02:00
Markos Gogoulos
e8d3ff25be Disable encoding and show only original file (#829)
Disable encoding and show only original file #829
2023-11-10 14:25:10 +02:00
Markos Gogoulos
15d217453b Update admins_docs.md (#842) 2023-07-17 16:47:06 +03:00
10 changed files with 139 additions and 15 deletions

View File

@@ -64,7 +64,7 @@ We have three goals for MediaCMS: a) deliver all functionality one would expect
## License
MediaCMS is released under [GNU Affero General Public License v3.0 license](LICENSE.txt).
Copyright Markos Gogoulos and Yiannis Stergiou
Copyright Markos Gogoulos.
## Support and paid services

View File

@@ -59,7 +59,7 @@ def login():
file.writelines(f'USERNAME={json.loads(response.text)["username"]}\n')
print(f"Welcome to MediaCMS [bold blue]{username}[/bold blue]. Your auth creds have been suceesfully stored in the .env file", ":v:")
else:
print(f'Error: {"non_field_errors":["User not found."]}')
print(f'Error: {"non_field_errors": ["User not found."]}')
@apis.command()
@@ -73,7 +73,7 @@ def upload_media():
if os.path.isdir(path):
for filename in os.listdir(path):
files = {}
abs = os.path.abspath("{path}/{filename}")
abs = os.path.abspath(f"{path}/{filename}")
files['media_file'] = open(f'{abs}', 'rb')
response = requests.post(url=f'{BASE_URL}/media', headers=headers, files=files)
if response.status_code == 201:

View File

@@ -93,6 +93,9 @@ ALLOW_MENTION_IN_COMMENTS = False # allowing to mention other users with @ in t
# valid options: content, author
RELATED_MEDIA_STRATEGY = "content"
# Whether or not to generate a sitemap.xml listing the pages on the site (default: False)
GENERATE_SITEMAP = False
USE_I18N = True
USE_L10N = True
USE_TZ = True
@@ -467,7 +470,7 @@ except ImportError:
if "http" not in FRONTEND_HOST:
# FRONTEND_HOST needs a http:// preffix
FRONTEND_HOST = f"http://{FRONTEND_HOST}"
FRONTEND_HOST = f"http://{FRONTEND_HOST}" # noqa
if LOCAL_INSTALL:
SSL_FRONTEND_HOST = FRONTEND_HOST.replace("http", "https")
@@ -486,4 +489,7 @@ if GLOBAL_LOGIN_REQUIRED:
r'/api/v[0-9]+/',
]
# if True, only show original, don't perform any action on videos
DO_NOT_TRANSCODE_VIDEO = False
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'

View File

@@ -18,7 +18,7 @@
- [15. Debugging email issues](#15-debugging-email-issues)
- [16. Frequently Asked Questions](#16-frequently-asked-questions)
- [17. Cookie consent code](#17-cookie-consent-code)
- [18. Disable encoding and show only original file](#18-disable-encoding-and-show-only-original-file)
## 1. Welcome
This page is created for MediaCMS administrators that are responsible for setting up the software, maintaining it and making modifications.
@@ -56,6 +56,15 @@ sudo systemctl restart mediacms celery_long celery_short # restart services
### Update from version 2 to version 3
Version 3 is using Django 4 and Celery 5, and needs a recent Python 3.x version. If you are updating from an older version, make sure Python is updated first. Version 2 could run on Python 3.6, but version 3 needs Python3.8 and higher.
The syntax for starting Celery has also changed, so you have to copy the celery related systemctl files and restart
```
# cp deploy/local_install/celery_long.service /etc/systemd/system/celery_long.service
# cp deploy/local_install/celery_short.service /etc/systemd/system/celery_short.service
# cp deploy/local_install/celery_beat.service /etc/systemd/system/celery_beat.service
# systemctl daemon-reload
# systemctl start celery_long celery_short celery_beat
```
@@ -461,6 +470,14 @@ ADMINS_NOTIFICATIONS = {
- Make the portal workflow public, but at the same time set `GLOBAL_LOGIN_REQUIRED = True` so that only logged in users can see content.
- You can either set `REGISTER_ALLOWED = False` if you want to add members yourself or checkout options on "django-allauth settings" that affects registration in `cms/settings.py`. Eg set the portal invite only, or set email confirmation as mandatory, so that you control who registers.
### 5.24 Enable the sitemap
Whether or not to enable generation of a sitemap file at http://your_installation/sitemap.xml (default: False)
```
GENERATE_SITEMAP = False
```
## 6. Manage pages
to be written
@@ -753,3 +770,12 @@ this will re-create the sprites for videos that the task failed.
On file `templates/components/header.html` you can find a simple cookie consent code. It is commented, so you have to remove the `{% comment %}` and `{% endcomment %}` lines in order to enable it. Or you can replace that part with your own code that handles cookie consent banners.
![Simple Cookie Consent](images/cookie_consent.png)
## 18. Disable encoding and show only original file
When videos are uploaded, they are getting encoded to multiple resolutions, a procedure called transcoding. Sometimes this is not needed and you only need to show the original file, eg when MediaCMS is running on a low capabilities server. To achieve this, edit settings.py and set
```
DO_NOT_TRANSCODE_VIDEO = True
```
This will disable the transcoding process and only the original file will be shown. Note that this will also disable the sprites file creation, so you will not have the preview thumbnails on the video player.

View File

@@ -538,8 +538,8 @@ def get_base_ffmpeg_command(
target_width = round(target_height * 16 / 9)
scale_filter_opts = [
f"if(lt(iw\\,ih)\\,{target_height}\\,{target_width})",
f"if(lt(iw\\,ih)\\,{target_width}\\,{target_height})",
f"if(lt(iw\\,ih)\\,{target_height}\\,{target_width})", # noqa
f"if(lt(iw\\,ih)\\,{target_width}\\,{target_height})", # noqa
"force_original_aspect_ratio=decrease",
"force_divisible_by=2",
"flags=lanczos",

View File

@@ -430,8 +430,13 @@ class Media(models.Model):
self.set_media_type()
if self.media_type == "video":
self.set_thumbnail(force=True)
self.produce_sprite_from_video()
self.encode()
if settings.DO_NOT_TRANSCODE_VIDEO:
self.encoding_status = "success"
self.save()
self.produce_sprite_from_video()
else:
self.produce_sprite_from_video()
self.encode()
elif self.media_type == "image":
self.set_thumbnail(force=True)
return True
@@ -667,6 +672,13 @@ class Media(models.Model):
return ret
for key in ENCODE_RESOLUTIONS_KEYS:
ret[key] = {}
# if this is enabled, return original file on a way
# that video.js can consume
if settings.DO_NOT_TRANSCODE_VIDEO:
ret['0-original'] = {"h264": {"url": helpers.url_from_path(self.media_file.path), "status": "success", "progress": 100}}
return ret
for encoding in self.encodings.select_related("profile").filter(chunk=False):
if encoding.profile.extension == "gif":
continue

View File

@@ -89,3 +89,6 @@ urlpatterns = [
re_path(r"^manage/media$", views.manage_media, name="manage_media"),
re_path(r"^manage/users$", views.manage_users, name="manage_users"),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
if hasattr(settings, "GENERATE_SITEMAP") and settings.GENERATE_SITEMAP:
urlpatterns.append(path("sitemap.xml", views.sitemap, name="sitemap"))

View File

@@ -292,6 +292,16 @@ def search(request):
return render(request, "cms/search.html", context)
def sitemap(request):
"""Sitemap"""
context = {}
context["media"] = list(Media.objects.filter(Q(listable=True)).order_by("-add_date"))
context["playlists"] = list(Playlist.objects.filter().order_by("-add_date"))
context["users"] = list(User.objects.filter())
return render(request, "sitemap.xml", context, content_type="application/xml")
def tags(request):
"""List tags view"""

View File

@@ -1,2 +1,3 @@
User-Agent: *
Allow: /
Sitemap: {{ FRONTEND_HOST }}/sitemap.xml

66
templates/sitemap.xml Normal file
View File

@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{% load static %}
<url>
<loc>{{ FRONTEND_HOST }}</loc>
<changefreq>always</changefreq>
</url>
<url>
<loc>{{ FRONTEND_HOST }}/featured</loc>
<changefreq>daily</changefreq>
</url>
<url>
<loc>{{ FRONTEND_HOST }}/recommended</loc>
<changefreq>always</changefreq>
</url>
<url>
<loc>{{ FRONTEND_HOST }}/latest</loc>
<changefreq>hourly</changefreq>
</url>
<url>
<loc>{{ FRONTEND_HOST }}/members</loc>
<changefreq>daily</changefreq>
</url>
<url>
<loc>{{ FRONTEND_HOST }}/tags</loc>
<changefreq>daily</changefreq>
</url>
<url>
<loc>{{ FRONTEND_HOST }}/categories</loc>
<changefreq>weekly</changefreq>
</url>
<url>
<loc>{{ FRONTEND_HOST }}/history</loc>
<changefreq>always</changefreq>
</url>
<url>
<loc>{{ FRONTEND_HOST }}/liked</loc>
</url>
<url>
<loc>{{ FRONTEND_HOST }}/about</loc>
<changefreq>monthly</changefreq>
</url>
<url>
<loc>{{ FRONTEND_HOST }}/tos</loc>
<changefreq>monthly</changefreq>
</url>
<url>
<loc>{{ FRONTEND_HOST }}/contact</loc>
<changefreq>never</changefreq>
</url>
{% for media_object in media %}
<url>
<loc>{{ FRONTEND_HOST}}/view?m={{ media_object.friendly_token }}</loc>
</url>
{% endfor %}
{% for playlist_object in playlists %}
<url>
<loc>{{ FRONTEND_HOST}}/playlists/{{ playlist_object.friendly_token }}</loc>
</url>
{% endfor %}
{% for user_object in users %}
<url>
<loc>{{ FRONTEND_HOST}}/user/{{ user_object.username }}/</loc>
</url>
{% endfor %}
</urlset>