Mohammed Khan 1 år sedan
förälder
incheckning
208e4abd29

+ 1 - 1
backend/UnTube/settings/__init__.py

@@ -20,7 +20,7 @@ if not os.path.isabs(LOCAL_SETTINGS_PATH):  # always make sure to have the absol
 
 include(
     'base.py',
-    # 'logging.py',
+    'logging.py',
     # 'rest_framework.py',
     # 'channels.py',
     # 'aws.py',

+ 0 - 1
backend/UnTube/settings/custom.py

@@ -12,6 +12,5 @@ CRISPY_TEMPLATE_PACK = 'bootstrap4'
 IN_PYTHONANYWHERE = False  # PA has PYTHONANYWHERE_SITE in its env
 IN_DOCKER = False
 
-ENABLE_PRINT_STATEMENTS = False  # runs the custom print_() statement that will log outputs to terminal
 STOKEN_EXPIRATION_SECONDS = 10
 USE_ON_COMMIT_HOOK = True

+ 27 - 0
backend/UnTube/settings/logging.py

@@ -0,0 +1,27 @@
+LOGGING = {
+    'version': 1,
+    'disable_existing_loggers': False,
+    'formatters': {
+        'standard': {
+            'format': '%(asctime)s %(levelname)s %(name)s %(message)s'
+        },
+    },
+    'handlers': {
+        'console': {
+            'level': 'INFO',
+            'class': 'logging.StreamHandler',
+            'formatter': 'standard',
+            'filters': [],
+        },
+    },
+    'loggers': {
+        logger_name: {
+            'level': 'WARNING',
+            'propagate': True,
+        } for logger_name in ('django', 'django.request', 'django.db.backends', 'django.template', 'backend')
+    },
+    'root': {
+        'level': 'DEBUG',
+        'handlers': ['console'],
+    }
+}

+ 9 - 1
backend/UnTube/settings/templates/settings.dev.py

@@ -1,6 +1,5 @@
 DEBUG = True
 SECRET_KEY = 'django-insecure-ycs22y+20sq67y(6dm6ynqw=dlhg!)%vuqpd@$p6rf3!#1h$u='
-ENABLE_PRINT_STATEMENTS = False
 
 GOOGLE_OAUTH_URI = '127.0.0.1:8000'  # this is the URI you will use when creating your OAuth Creds
 SITE_ID = 1  # increment/decrement site ID as necessary
@@ -8,3 +7,12 @@ SITE_ID = 1  # increment/decrement site ID as necessary
 # please fill these in with your own Google OAuth credentials for the app to run properly!
 GOOGLE_OAUTH_CLIENT_ID = NotImplemented
 GOOGLE_OAUTH_CLIENT_SECRET = NotImplemented
+
+# update logger to display DEBUG level or higher logs (+ color the logs using the colorlog package)
+LOGGING['formatters']['colored'] = {  # type: ignore
+    '()': 'colorlog.ColoredFormatter',
+    'format': '%(log_color)s%(asctime)s %(levelname)s %(name)s %(bold_white)s%(message)s',
+}
+LOGGING['loggers']['backend']['level'] = 'DEBUG'  # type: ignore
+LOGGING['handlers']['console']['level'] = 'DEBUG'  # type: ignore
+LOGGING['handlers']['console']['formatter'] = 'colored'  # type: ignore

+ 0 - 6
backend/general/utils/misc.py

@@ -1,5 +1,4 @@
 import yaml
-from django.conf import settings
 
 
 def yaml_coerce(value):
@@ -13,8 +12,3 @@ def yaml_coerce(value):
         return yaml.load(f'dummy: {value}', Loader=yaml.SafeLoader)['dummy']
 
     return value
-
-
-def print_(*args, **kwargs):
-    if settings.ENABLE_PRINT_STATEMENTS:
-        print(*args, **kwargs)

+ 30 - 28
backend/main/models.py

@@ -5,7 +5,9 @@ from django.db import models
 from googleapiclient.discovery import build
 import googleapiclient.errors
 from django.db.models import Q, Sum
-from ..general.utils.misc import print_
+import logging
+
+logger = logging.getLogger(__name__)
 
 
 def get_message_from_httperror(e):
@@ -60,10 +62,10 @@ class PlaylistManager(models.Manager):
 
             pl_response = pl_request.execute()
 
-            print_(pl_response)
+            logger.debug(pl_response)
 
             if pl_response['pageInfo']['totalResults'] == 0:
-                print_(
+                logger.warning(
                     'Looks like do not have a channel on youtube. Create one to import all of your playlists. Retry?'
                 )
                 return -1
@@ -103,7 +105,7 @@ class PlaylistManager(models.Manager):
                     maxResults=50
                 )
             else:
-                print_('GETTING ALL USER AUTH PLAYLISTS')
+                logger.debug('GETTING ALL USER AUTH PLAYLISTS')
                 pl_request = youtube.playlists().list(
                     part='contentDetails, snippet, id, player, status',
                     mine=True,  # get playlist details for this playlist id
@@ -114,15 +116,15 @@ class PlaylistManager(models.Manager):
             try:
                 pl_response = pl_request.execute()
             except googleapiclient.errors.HttpError as e:
-                print_('YouTube channel not found if mine=True')
-                print_('YouTube playlist not found if id=playlist_id')
+                logger.debug('YouTube channel not found if mine=True')
+                logger.debug('YouTube playlist not found if id=playlist_id')
                 result['status'] = -1
                 result['error_message'] = get_message_from_httperror(e)
                 return result
 
-            print_(pl_response)
+            logger.debug(pl_response)
             if pl_response['pageInfo']['totalResults'] == 0:
-                print_('No playlists created yet on youtube.')
+                logger.warning('No playlists created yet on youtube.')
                 result['status'] = -2
                 return result
 
@@ -151,7 +153,7 @@ class PlaylistManager(models.Manager):
             # check if this playlist already exists in user's untube collection
             if user.playlists.filter(Q(playlist_id=playlist_id) & Q(is_in_db=True)).exists():
                 playlist = user.playlists.get(playlist_id=playlist_id)
-                print_(f'PLAYLIST {playlist.name} ({playlist_id}) ALREADY EXISTS IN DB')
+                logger.debug(f'PLAYLIST {playlist.name} ({playlist_id}) ALREADY EXISTS IN DB')
 
                 # POSSIBLE CASES:
                 # 1. PLAYLIST HAS DUPLICATE VIDEOS, DELETED VIDS, UNAVAILABLE VIDS
@@ -165,7 +167,7 @@ class PlaylistManager(models.Manager):
                     result['status'] = -3
                     return result
             else:  # no such playlist in database
-                print_(f'CREATING {item["snippet"]["title"]} ({playlist_id})')
+                logger.debug(f'CREATING {item["snippet"]["title"]} ({playlist_id})')
                 if user.playlists.filter(Q(playlist_id=playlist_id) & Q(is_in_db=False)).exists():
                     unimported_playlist = user.playlists.filter(Q(playlist_id=playlist_id) & Q(is_in_db=False)).first()
                     unimported_playlist.delete()
@@ -263,7 +265,7 @@ class PlaylistManager(models.Manager):
 
                 else:  # video found in user's db
                     if playlist.playlist_items.filter(playlist_item_id=playlist_item_id).exists():
-                        print_('PLAYLIST ITEM ALREADY EXISTS')
+                        logger.debug('PLAYLIST ITEM ALREADY EXISTS')
                         continue
 
                     video = user.videos.get(video_id=video_id)
@@ -454,7 +456,7 @@ class PlaylistManager(models.Manager):
         # if its been a week since the last full scan, do a full playlist scan
         # basically checks all the playlist video for any updates
         if playlist.last_full_scan_at + datetime.timedelta(minutes=1) < datetime.datetime.now(pytz.utc):
-            print_('DOING A FULL SCAN')
+            logger.debug('DOING A FULL SCAN')
             current_playlist_item_ids = [
                 playlist_item.playlist_item_id for playlist_item in playlist.playlist_items.all()
             ]
@@ -542,7 +544,7 @@ class PlaylistManager(models.Manager):
 
             return [1, deleted_videos, unavailable_videos, added_videos]
         else:
-            print_(
+            logger.warning(
                 'YOU CAN DO A FULL SCAN AGAIN IN',
                 str(datetime.datetime.now(pytz.utc) - (playlist.last_full_scan_at + datetime.timedelta(minutes=1)))
             )
@@ -625,10 +627,10 @@ class PlaylistManager(models.Manager):
             try:
                 pl_response = pl_request.execute()
             except googleapiclient.errors.HttpError:
-                print_('Playist was deleted on YouTube')
+                logger.info('Playist was deleted on YouTube')
                 return [-1, [], [], []]
 
-            print_('ESTIMATED VIDEO IDS FROM RESPONSE', len(pl_response['items']))
+            logger.debug('ESTIMATED VIDEO IDS FROM RESPONSE', len(pl_response['items']))
             updated_playlist_video_count += len(pl_response['items'])
             for item in pl_response['items']:
                 playlist_item_id = item['id']
@@ -928,13 +930,13 @@ class PlaylistManager(models.Manager):
             pl_request = youtube.playlists().delete(id=playlist_id)
             try:
                 pl_response = pl_request.execute()
-                print_(pl_response)
+                logger.debug(pl_response)
             except googleapiclient.errors.HttpError as e:  # failed to delete playlist
                 # possible causes:
                 # playlistForbidden (403)
                 # playlistNotFound  (404)
                 # playlistOperationUnsupported (400)
-                print_(e.error_details, e.status_code)
+                logger.debug(e.error_details, e.status_code)
                 return [-1, get_message_from_httperror(e), e.status_code]
 
             # playlistItem was successfully deleted if no HttpError, so delete it from db
@@ -962,16 +964,16 @@ class PlaylistManager(models.Manager):
         with build('youtube', 'v3', credentials=credentials) as youtube:
             for playlist_item in playlist_items:
                 pl_request = youtube.playlistItems().delete(id=playlist_item.playlist_item_id)
-                print_(pl_request)
+                logger.debug(pl_request)
                 try:
                     pl_response = pl_request.execute()
-                    print_(pl_response)
+                    logger.debug(pl_response)
                 except googleapiclient.errors.HttpError as e:  # failed to delete playlist item
                     # possible causes:
                     # playlistItemsNotAccessible (403)
                     # playlistItemNotFound (404)
                     # playlistOperationUnsupported (400)
-                    print_(e, e.error_details, e.status_code)
+                    logger.debug(e, e.error_details, e.status_code)
                     continue
 
                 # playlistItem was successfully deleted if no HttpError, so delete it from db
@@ -1055,7 +1057,7 @@ class PlaylistManager(models.Manager):
             try:
                 pl_response = pl_request.execute()
             except googleapiclient.errors.HttpError as e:  # failed to create playlist
-                print_(e.status_code, e.error_details)
+                logger.debug(e.status_code, e.error_details)
                 if e.status_code == 400:  # maxPlaylistExceeded
                     result['status'] = 400
                 result['status'] = -1
@@ -1085,7 +1087,7 @@ class PlaylistManager(models.Manager):
                 },
             )
 
-            print_(details['description'])
+            logger.debug(details['description'])
             try:
                 pl_response = pl_request.execute()
             except googleapiclient.errors.HttpError as e:  # failed to update playlist details
@@ -1095,10 +1097,10 @@ class PlaylistManager(models.Manager):
                 # playlistOperationUnsupported (400)
                 # errors i ran into:
                 # runs into HttpError 400 'Invalid playlist snippet.' when the description contains <, >
-                print_('ERROR UPDATING PLAYLIST DETAILS', e, e.status_code, e.error_details)
+                logger.debug('ERROR UPDATING PLAYLIST DETAILS', e, e.status_code, e.error_details)
                 return -1
 
-            print_(pl_response)
+            logger.debug(pl_response)
             playlist.name = pl_response['snippet']['title']
             playlist.description = pl_response['snippet']['description']
             playlist.is_private_on_yt = True if pl_response['status']['privacyStatus'] == 'private' else False
@@ -1148,7 +1150,7 @@ class PlaylistManager(models.Manager):
                         # playlistOperationUnsupported (400)
                         # errors i ran into:
                         # runs into HttpError 400 'Invalid playlist snippet.' when the description contains <, >
-                        print_('ERROR UPDATING PLAYLIST DETAILS', e.status_code, e.error_details)
+                        logger.debug('ERROR UPDATING PLAYLIST DETAILS', e.status_code, e.error_details)
                         if e.status_code == 400:
                             pl_request = youtube.playlistItems().insert(
                                 part='snippet',
@@ -1167,7 +1169,7 @@ class PlaylistManager(models.Manager):
                                 # pl_response = pl_request.execute()
                                 pl_request.execute()
                             except googleapiclient.errors.HttpError as e:
-                                print_(e)
+                                logger.debug(e)
                                 result['status'] = -1
                         elif e.status_code == 403:
                             result['playlistContainsMaximumNumberOfVideos'] = True
@@ -1213,7 +1215,7 @@ class PlaylistManager(models.Manager):
                     # pl_response = pl_request.execute()
                     pl_request.execute()
                 except googleapiclient.errors.HttpError as e:  # failed to update add video to playlis
-                    print_('ERROR ADDDING VIDEOS TO PLAYLIST', e.status_code, e.error_details)
+                    logger.debug('ERROR ADDDING VIDEOS TO PLAYLIST', e.status_code, e.error_details)
                     if e.status_code == 400:  # manualSortRequired - see errors https://developers.google.com/youtube/v3/docs/playlistItems/insert
                         pl_request = youtube.playlistItems().insert(
                             part='snippet',
@@ -1231,7 +1233,7 @@ class PlaylistManager(models.Manager):
                             # pl_response = pl_request.execute()
                             pl_request.execute()
                         except googleapiclient.errors.HttpError as e:  # failed to update playlist details
-                            print_(e)
+                            logger.debug(e)
                             pass
                     elif e.status_code == 403:
                         result['playlistContainsMaximumNumberOfVideos'] = True

+ 13 - 12
backend/main/views.py

@@ -8,10 +8,11 @@ from django.http import HttpResponse
 from django.shortcuts import get_object_or_404, redirect, render
 from django.template import loader
 from django.views.decorators.http import require_POST
-
-from ..general.utils.misc import print_
 from .models import Playlist, Tag
 from .util import *
+import logging
+
+logger = logging.getLogger(__name__)
 
 
 # Create your views here.
@@ -143,7 +144,7 @@ def view_playlist(request, playlist_id):
         # if its been 1 days since the last full scan, force refresh the playlist
         if playlist.last_full_scan_at + datetime.timedelta(days=2) < datetime.datetime.now(pytz.utc):
             playlist.has_playlist_changed = True
-            print_('ITS BEEN 15 DAYS, FORCE REFRESHING PLAYLIST')
+            logger.info('ITS BEEN 15 DAYS, FORCE REFRESHING PLAYLIST')
 
         # only note down that the playlist as been viewed when 30s has passed since the last access
         if playlist.last_accessed_on + datetime.timedelta(seconds=30) < datetime.datetime.now(pytz.utc):
@@ -488,7 +489,7 @@ def playlist_delete_videos(request, playlist_id, command):
             """
         )
     elif command == 'start':
-        print_('Deleting', len(playlist_item_ids), 'videos')
+        logger.info('Deleting', len(playlist_item_ids), 'videos')
         Playlist.objects.deletePlaylistItems(request.user, playlist_id, playlist_item_ids)
         if all_:
             help_text = 'Finished emptying this playlist.'
@@ -599,7 +600,7 @@ def load_more_videos(request, playlist_id, order_by, page):
     playlist_items = None
     if order_by == 'all':
         playlist_items = playlist.playlist_items.select_related('video').order_by('video_position')
-        print_(f'loading page 1: {playlist_items.count()} videos')
+        logger.debug(f'loading page 1: {playlist_items.count()} videos')
     elif order_by == 'favorites':
         playlist_items = playlist.playlist_items.select_related('video').filter(video__is_favorite=True
                                                                                 ).order_by('video_position')
@@ -703,13 +704,13 @@ def update_playlist(request, playlist_id, command):
     playlist = request.user.playlists.get(playlist_id=playlist_id)
 
     if command == 'checkforupdates':
-        print_('Checking if playlist changed...')
+        logger.debug('Checking if playlist changed...')
         result = Playlist.objects.checkIfPlaylistChangedOnYT(request.user, playlist_id)
 
         if result[0] == 1:  # full scan was done (full scan is done for a playlist if a week has passed)
             deleted_videos, unavailable_videos, added_videos = result[1:]
 
-            print_('CHANGES', deleted_videos, unavailable_videos, added_videos)
+            logger.debug('CHANGES', deleted_videos, unavailable_videos, added_videos)
 
             # playlist_changed_text = ['The following modifications happened to this playlist on YouTube:']
             if deleted_videos != 0 or unavailable_videos != 0 or added_videos != 0:
@@ -738,7 +739,7 @@ def update_playlist(request, playlist_id, command):
                 """
                 )
         elif result[0] == -1:  # playlist changed
-            print_('Playlist was deleted from YouTube')
+            logger.debug('Playlist was deleted from YouTube')
             playlist.videos.all().delete()
             playlist.delete()
             return HttpResponse(
@@ -779,7 +780,7 @@ def update_playlist(request, playlist_id, command):
         )
 
     if command == 'manual':
-        print_('MANUAL')
+        logger.debug('MANUAL')
         return HttpResponse(
             f"""<div hx-get='/playlist/{playlist_id}/update/auto' hx-trigger='load' hx-swap='outerHTML'>
                     <div class='d-flex justify-content-center mt-4 mb-3' id='loading-sign'>
@@ -790,7 +791,7 @@ def update_playlist(request, playlist_id, command):
                 </div>"""
         )
 
-    print_('Attempting to update playlist')
+    logger.debug('Attempting to update playlist')
     status, deleted_playlist_item_ids, unavailable_videos, added_videos = Playlist.objects.updatePlaylist(
         request.user, playlist_id
     )
@@ -809,7 +810,7 @@ def update_playlist(request, playlist_id, command):
             """
         )
 
-    print_('Updated playlist')
+    logger.debug('Updated playlist')
     playlist_changed_text = []
 
     if len(added_videos) != 0:
@@ -977,7 +978,7 @@ def remove_playlist_tag(request, playlist_id, tag_name):
     if playlist_tags.filter(name__iexact=tag_name).exists():  # tag on this playlist, remove it it
         tag = Tag.objects.filter(Q(created_by=request.user) & Q(name__iexact=tag_name)).first()
 
-        print_('Removed tag', tag_name)
+        logger.debug('Removed tag', tag_name)
         # remove it from the playlist
         playlist.tags.remove(tag)
     else:

+ 3 - 2
backend/search/views.py

@@ -5,14 +5,15 @@ from django.http import HttpResponse
 from django.shortcuts import redirect, render
 from django.template import loader
 from django.views.decorators.http import require_POST
+import logging
 
-from backend.general.utils.misc import print_
+logger = logging.getLogger(__name__)
 
 
 @login_required
 def search(request):
     if request.method == 'GET':
-        print_(request.GET)
+        logger.debug(request.GET)
         if 'mode' in request.GET:
             mode = bleach.clean(request.GET['mode'])
         else:

+ 10 - 10
backend/users/views.py

@@ -11,11 +11,11 @@ from django.http import HttpResponse
 from django.shortcuts import redirect, render
 from django.template import loader
 from django.views.decorators.http import require_POST
-
 from backend.main.models import Playlist
-
-from ..general.utils.misc import print_
 from .models import Untube
+import logging
+
+logger = logging.getLogger(__name__)
 
 
 # Create your views here.
@@ -258,18 +258,18 @@ def continue_import(request):
         return redirect('home')
 
     num_of_playlists = request.user.playlists.filter(Q(is_user_owned=True)).exclude(playlist_id='LL').count()
-    print_('NUM OF PLAYLISTS', num_of_playlists)
+    logger.debug('NUM OF PLAYLISTS', num_of_playlists)
     try:
         remaining_playlists = request.user.playlists.filter(Q(is_user_owned=True) &
                                                             Q(is_in_db=False)).exclude(playlist_id='LL')
-        print_(remaining_playlists.count(), 'REMAINING PLAYLISTS')
+        logger.debug(remaining_playlists.count(), 'REMAINING PLAYLISTS')
         playlists_imported = num_of_playlists - remaining_playlists.count() + 1
         playlist = remaining_playlists.order_by('created_at')[0]
         playlist_name = playlist.name
         playlist_id = playlist.playlist_id
         Playlist.objects.getAllVideosForPlaylist(request.user, playlist_id)
     except Exception:
-        print_('NO REMAINING PLAYLISTS')
+        logger.debug('NO REMAINING PLAYLISTS')
         playlist_id = -1
 
     if playlist_id != -1:
@@ -316,7 +316,7 @@ def user_playlists_updates(request, action):
 
         result = Playlist.objects.initializePlaylist(request.user)
 
-        print_(result)
+        logger.debug(result)
         youtube_playlist_ids = result['playlist_ids']
         untube_playlist_ids = []
         for playlist in user_playlists_on_UnTube:
@@ -332,15 +332,15 @@ def user_playlists_updates(request, action):
                 pl.delete()
 
         if result['num_of_playlists'] == user_playlists_on_UnTube.count() and len(deleted_playlist_ids) == 0:
-            print_('No new updates')
+            logger.info('No new updates')
             playlists = []
         else:
             playlists = request.user.playlists.filter(Q(is_user_owned=True) &
                                                       Q(is_in_db=False)).exclude(playlist_id='LL')
-            print_(
+            logger.info(
                 f'New updates found! {playlists.count()} newly added and {len(deleted_playlist_ids)} playlists deleted!'
             )
-            print_(deleted_playlist_names)
+            logger.info(deleted_playlist_names)
 
         return HttpResponse(
             loader.get_template('intercooler/user_playlist_updates.html').render({

+ 31 - 1
poetry.lock

@@ -235,6 +235,36 @@ files = [
     {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"},
 ]
 
+[[package]]
+name = "colorama"
+version = "0.4.6"
+description = "Cross-platform colored terminal text."
+category = "dev"
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
+files = [
+    {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
+    {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
+]
+
+[[package]]
+name = "colorlog"
+version = "6.7.0"
+description = "Add colours to the output of Python's logging module."
+category = "dev"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "colorlog-6.7.0-py2.py3-none-any.whl", hash = "sha256:0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662"},
+    {file = "colorlog-6.7.0.tar.gz", hash = "sha256:bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5"},
+]
+
+[package.dependencies]
+colorama = {version = "*", markers = "sys_platform == \"win32\""}
+
+[package.extras]
+development = ["black", "flake8", "mypy", "pytest", "types-colorama"]
+
 [[package]]
 name = "cryptography"
 version = "40.0.2"
@@ -1169,4 +1199,4 @@ files = [
 [metadata]
 lock-version = "2.0"
 python-versions = "^3.10"
-content-hash = "d9d46ef9477a9fbbd4d8033b1aebd0d029a35cb98f9ac3b784b5087ad8ab7521"
+content-hash = "0399ac6af9494d7230d72fca3134e865bec4cd4fde1578b6ec7bda7bec875388"

+ 1 - 0
pyproject.toml

@@ -26,6 +26,7 @@ django-import-export = "^3.2.0"
 
 [tool.poetry.group.dev.dependencies]
 pre-commit = "^3.3.2"
+colorlog = "^6.7.0"
 
 [build-system]
 requires = ["poetry-core"]