Merge pull request #8703 from dstftw/mark-watched
Add --mark-watched feature (Closes #5054)
This commit is contained in:
		@@ -355,6 +355,7 @@ def _real_main(argv=None):
 | 
			
		||||
        'youtube_include_dash_manifest': opts.youtube_include_dash_manifest,
 | 
			
		||||
        'encoding': opts.encoding,
 | 
			
		||||
        'extract_flat': opts.extract_flat,
 | 
			
		||||
        'mark_watched': opts.mark_watched,
 | 
			
		||||
        'merge_output_format': opts.merge_output_format,
 | 
			
		||||
        'postprocessors': postprocessors,
 | 
			
		||||
        'fixup': opts.fixup,
 | 
			
		||||
 
 | 
			
		||||
@@ -1620,6 +1620,15 @@ class InfoExtractor(object):
 | 
			
		||||
    def _get_automatic_captions(self, *args, **kwargs):
 | 
			
		||||
        raise NotImplementedError('This method must be implemented by subclasses')
 | 
			
		||||
 | 
			
		||||
    def mark_watched(self, *args, **kwargs):
 | 
			
		||||
        if (self._downloader.params.get('mark_watched', False) and
 | 
			
		||||
                (self._get_login_info()[0] is not None or
 | 
			
		||||
                    self._downloader.params.get('cookiefile') is not None)):
 | 
			
		||||
            self._mark_watched(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def _mark_watched(self, *args, **kwargs):
 | 
			
		||||
        raise NotImplementedError('This method must be implemented by subclasses')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SearchInfoExtractor(InfoExtractor):
 | 
			
		||||
    """
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@ from __future__ import unicode_literals
 | 
			
		||||
import itertools
 | 
			
		||||
import json
 | 
			
		||||
import os.path
 | 
			
		||||
import random
 | 
			
		||||
import re
 | 
			
		||||
import time
 | 
			
		||||
import traceback
 | 
			
		||||
@@ -1046,6 +1047,29 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
 | 
			
		||||
            self._downloader.report_warning(err_msg)
 | 
			
		||||
            return {}
 | 
			
		||||
 | 
			
		||||
    def _mark_watched(self, video_id, video_info):
 | 
			
		||||
        playback_url = video_info.get('videostats_playback_base_url', [None])[0]
 | 
			
		||||
        if not playback_url:
 | 
			
		||||
            return
 | 
			
		||||
        parsed_playback_url = compat_urlparse.urlparse(playback_url)
 | 
			
		||||
        qs = compat_urlparse.parse_qs(parsed_playback_url.query)
 | 
			
		||||
 | 
			
		||||
        # cpn generation algorithm is reverse engineered from base.js.
 | 
			
		||||
        # In fact it works even with dummy cpn.
 | 
			
		||||
        CPN_ALPHABET = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_'
 | 
			
		||||
        cpn = ''.join((CPN_ALPHABET[random.randint(0, 256) & 63] for _ in range(0, 16)))
 | 
			
		||||
 | 
			
		||||
        qs.update({
 | 
			
		||||
            'ver': ['2'],
 | 
			
		||||
            'cpn': [cpn],
 | 
			
		||||
        })
 | 
			
		||||
        playback_url = compat_urlparse.urlunparse(
 | 
			
		||||
            parsed_playback_url._replace(query=compat_urllib_parse.urlencode(qs, True)))
 | 
			
		||||
 | 
			
		||||
        self._download_webpage(
 | 
			
		||||
            playback_url, video_id, 'Marking watched',
 | 
			
		||||
            'Unable to mark watched', fatal=False)
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def extract_id(cls, url):
 | 
			
		||||
        mobj = re.match(cls._VALID_URL, url, re.VERBOSE)
 | 
			
		||||
@@ -1555,6 +1579,8 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
 | 
			
		||||
 | 
			
		||||
        self._sort_formats(formats)
 | 
			
		||||
 | 
			
		||||
        self.mark_watched(video_id, video_info)
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            'id': video_id,
 | 
			
		||||
            'uploader': video_uploader,
 | 
			
		||||
 
 | 
			
		||||
@@ -170,6 +170,10 @@ def parseOpts(overrideArguments=None):
 | 
			
		||||
        action='store_const', dest='extract_flat', const='in_playlist',
 | 
			
		||||
        default=False,
 | 
			
		||||
        help='Do not extract the videos of a playlist, only list them.')
 | 
			
		||||
    general.add_option(
 | 
			
		||||
        '--mark-watched',
 | 
			
		||||
        action='store_true', dest='mark_watched', default=False,
 | 
			
		||||
        help='Mark videos watched (YouTube only)')
 | 
			
		||||
    general.add_option(
 | 
			
		||||
        '--no-color', '--no-colors',
 | 
			
		||||
        action='store_true', dest='no_color',
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user