Acfun: Fix Youku COOP ct85&86
diff --git a/src/you_get/extractors/acfun.py b/src/you_get/extractors/acfun.py
old mode 100644
new mode 100755
index e78d363627..983606d42f
--- a/src/you_get/extractors/acfun.py
+++ b/src/you_get/extractors/acfun.py
@@ -8,7 +8,7 @@
 from .qq import qq_download_by_vid
 from .sina import sina_download_by_vid
 from .tudou import tudou_download_by_iid
-from .youku import youku_download_by_vid
+from .youku import youku_download_by_vid, youku_open_download_by_vid
 
 import json, re
 
@@ -32,14 +32,11 @@ def acfun_download_by_vid(vid, title, output_dir='.', merge=True, info_only=Fals
     elif sourceType == 'letv':
         letvcloud_download_by_vu(sourceId, '2d8c027396', title, output_dir=output_dir, merge=merge, info_only=info_only)
     elif sourceType == 'zhuzhan':
-        a = 'http://api.aixifan.com/plays/%s/realSource' % vid
-        s = json.loads(get_content(a, headers={'deviceType': '1'}))
-        urls = s['data']['files'][-1]['url']
-        size = urls_size(urls)
-        print_info(site_info, title, 'mp4', size)
-        if not info_only:
-            download_urls(urls, title, 'mp4', size,
-                          output_dir=output_dir, merge=merge)
+        a = 'http://api.aixifan.com/plays/%s' % vid
+        s = json.loads(get_content(a, headers={'deviceType': '2'}))
+        if s['data']['source'] == "zhuzhan-youku":
+            sourceId = s['data']['sourceId']
+            youku_open_download_by_vid(client_id='908a519d032263f8', vid=sourceId, title=title, output_dir=output_dir, merge=merge, info_only=info_only, **kwargs)
     else:
         raise NotImplementedError(sourceType)
 
diff --git a/src/you_get/extractors/youku.py b/src/you_get/extractors/youku.py
index 3135e82251..fefaf5ee68 100644
--- a/src/you_get/extractors/youku.py
+++ b/src/you_get/extractors/youku.py
@@ -28,7 +28,11 @@ class Youku(VideoExtractor):
     f_code_1 = 'becaf9be'
     f_code_2 = 'bf7e5f01'
 
+    ctype = 12  #differ from 86
+
     def trans_e(a, c):
+        """str, str->str
+        This is an RC4 encryption."""
         f = h = 0
         b = list(range(256))
         result = ''
@@ -49,14 +53,14 @@ def trans_e(a, c):
 
         return result
 
-    def generate_ep(no, streamfileids, sid, token):
+    def generate_ep(self, no, streamfileids, sid, token):
         number = hex(int(str(no), 10))[2:].upper()
         if len(number) == 1:
             number = '0' + number
         fileid = streamfileids[0:8] + number + streamfileids[10:]
         ep = parse.quote(base64.b64encode(
-            ''.join(Youku.trans_e(
-                Youku.f_code_2,
+            ''.join(self.__class__.trans_e(
+                self.f_code_2,  #use the 86 fcode if using 86
                 sid + '_' + fileid + '_' + token)).encode('latin1')),
             safe='~()*!.\''
         )
@@ -150,8 +154,17 @@ def prepare(self, **kwargs):
                 self.download_playlist_by_url(self.url, **kwargs)
                 exit(0)
 
-        api_url = 'http://play.youku.com/play/get.json?vid=%s&ct=10' % self.vid
-        api12_url = 'http://play.youku.com/play/get.json?vid=%s&ct=12' % self.vid
+        #HACK!
+        if 'api_url' in kwargs:
+            api_url = kwargs['api_url']  #85
+            api12_url = kwargs['api12_url']  #86
+            self.ctype = kwargs['ctype']
+            self.title = kwargs['title']
+            
+        else:
+            api_url = 'http://play.youku.com/play/get.json?vid=%s&ct=10' % self.vid
+            api12_url = 'http://play.youku.com/play/get.json?vid=%s&ct=12' % self.vid
+
         try:
             meta = json.loads(get_content(
                 api_url,
@@ -187,7 +200,8 @@ def prepare(self, **kwargs):
             else:
                 log.wtf('[Failed] Video not found.')
 
-        self.title = data['video']['title']
+        if not self.title:  #86
+            self.title = data['video']['title']
         self.ep = data12['security']['encrypt_string']
         self.ip = data12['security']['ip']
 
@@ -264,7 +278,7 @@ def extract(self, **kwargs):
             stream_id = self.streams_sorted[0]['id']
 
         e_code = self.__class__.trans_e(
-            self.__class__.f_code_1,
+            self.f_code_1,
             base64.b64decode(bytes(self.ep, 'ascii'))
         )
         sid, token = e_code.split('_')
@@ -279,10 +293,10 @@ def extract(self, **kwargs):
                     for no in range(0, len(segs)):
                         k = segs[no]['key']
                         if k == -1: break # we hit the paywall; stop here
-                        fileid, ep = self.__class__.generate_ep(no, streamfileid,
+                        fileid, ep = self.__class__.generate_ep(self, no, streamfileid,
                                                                 sid, token)
                         q = parse.urlencode(dict(
-                            ctype = 12,
+                            ctype = self.ctype,
                             ev    = 1,
                             K     = k,
                             ep    = parse.unquote(ep),
@@ -312,9 +326,40 @@ def extract(self, **kwargs):
         if not kwargs['info_only']:
             self.streams[stream_id]['src'] = ksegs
 
+    def open_download_by_vid(self, client_id, vid, **kwargs):
+        """self, str, str, **kwargs->None
+        Override the original one with VideoExtractor.
+        Most of the credit are to @ERioK, who gave his POC."""
+        self.f_code_1 = '10ehfkbv'  #can be retrived by running r.translate with the keys and the list e
+        self.f_code_2 = 'msjv7h2b'
+        self.url = None
+        self.vid = vid
+        self.name = "优酷开放平台 (Youku COOP)"
+
+        #A little bit of work before self.prepare
+        sign_url = "https://api.youku.com/players/custom.json?client_id={client_id}&video_id={video_id}".format(client_id = client_id, video_id = vid)
+        playsign = json.loads(get_content(sign_url))['playsign']
+    
+        api85_url = 'http://play.youku.com/partner/get.json?cid={client_id}&vid={vid}&ct=85&sign={playsign}'.format(client_id = client_id, vid = vid, playsign = playsign)
+        api86_url = 'http://play.youku.com/partner/get.json?cid={client_id}&vid={vid}&ct=86&sign={playsign}'.format(client_id = client_id, vid = vid, playsign = playsign)
+        
+        self.prepare(api_url = api85_url, api12_url = api86_url, ctype = 86, **kwargs)
+        if 'extractor_proxy' in kwargs and kwargs['extractor_proxy']:
+            unset_proxy()
+
+        try:
+            self.streams_sorted = [dict([('id', stream_type['id'])] + list(self.streams[stream_type['id']].items())) for stream_type in self.__class__.stream_types if stream_type['id'] in self.streams]
+        except:
+            self.streams_sorted = [dict([('itag', stream_type['itag'])] + list(self.streams[stream_type['itag']].items())) for stream_type in self.__class__.stream_types if stream_type['itag'] in self.streams]
+
+        self.extract(**kwargs)
+
+        self.download(**kwargs)
+
 site = Youku()
 download = site.download_by_url
 download_playlist = site.download_playlist_by_url
 
 youku_download_by_vid = site.download_by_vid
+youku_open_download_by_vid = site.open_download_by_vid
 # Used by: acfun.py bilibili.py miomio.py tudou.py

So long everyone.

I apologize for the long delay due to unexpected physical and psychological conditions.

Also I want to thank for @zhangn1985 's enlightening discussions and @soimort 's effort. Specially I give the credit to @ERioK 's POC which guided me through this patch. 

There are more people I want to thank then who I could remember. Thanks a lot.

Beining

```
$ python3 you-get -di http://www.acfun.tv/v/ac2701527
[DEBUG] get_content: http://api.aixifan.com/plays/3462634
[DEBUG] get_content: https://api.youku.com/players/custom.json?client_id=908a519d032263f8&video_id=CMzQyMjc0NA==
[DEBUG] get_content: http://play.youku.com/partner/get.json?cid=908a519d032263f8&vid=CMzQyMjc0NA==&ct=85&sign=MXwxNDYxODIxNTAyfDI0MzZkOTYwMDNlMTIwMDRlZTg1OTRhZTAzZjI0OTc5
[DEBUG] get_content: http://play.youku.com/partner/get.json?cid=908a519d032263f8&vid=CMzQyMjc0NA==&ct=86&sign=MXwxNDYxODIxNTAyfDI0MzZkOTYwMDNlMTIwMDRlZTg1OTRhZTAzZjI0OTc5
[DEBUG] get_content: http://k.youku.com/player/getFlvPath/sid/946182150401686da3f3a_00/st/flv/fileid/0300010B0057203D92EA8F2D9B7D2F561017A4-4E51-68F3-B5BC-23EBF9BBC4EF?oip=1176176655&ep=Bp5ccxwBzLlAG0%2FH6Ajc9BK2CHGLmE%2FI6YrkNt1v%2FieiMqPqcylWvjS%2BJqkjN%2BP0ZzFvyk5pKqrRS1WSpdbnHJUPMfc3tDsJUJSOPVINsHf9OlYhsfDP2VDSqqnS&ctype=86&K=e7b5adeb3ee29562261efae3&yxon=1&ev=1&token=2412
[DEBUG] get_content: http://k.youku.com/player/getFlvPath/sid/946182150401686da3f3a_00/st/flv/fileid/0300010B0157203D92EA8F2D9B7D2F561017A4-4E51-68F3-B5BC-23EBF9BBC4EF?oip=1176176655&ep=Bp5ccxwBzLlAG0%2FH6Ajc9BK2CHGLmE%2FI6YrkNt1v%2FiaiMqPqcylWvjS%2BJqkjN%2BP0ZzFvyk5pKqrRS1WSpdbnHJUPMfc3tDsJUJSOPVINsHf9OlYhsfDP2VDSqqnS&ctype=86&K=69adefdb458eb9f6261efae3&yxon=1&ev=1&token=2412
[DEBUG] get_content: http://k.youku.com/player/getFlvPath/sid/946182150401686da3f3a_00/st/flv/fileid/0300010B0257203D92EA8F2D9B7D2F561017A4-4E51-68F3-B5BC-23EBF9BBC4EF?oip=1176176655&ep=Bp5ccxwBzLlAG0%2FH6Ajc9BK2CHGLmE%2FI6YrkNt1v%2FiWiMqPqcylWvjS%2BJqkjN%2BP0ZzFvyk5pKqrRS1WSpdbnHJUPMfc3tDsJUJSOPVINsHf9OlYhsfDP2VDSqqnS&ctype=86&K=47012544122ae5a5282b5f3e&yxon=1&ev=1&token=2412
[DEBUG] get_content: http://k.youku.com/player/getFlvPath/sid/946182150401686da3f3a_00/st/flv/fileid/0300010B0357203D92EA8F2D9B7D2F561017A4-4E51-68F3-B5BC-23EBF9BBC4EF?oip=1176176655&ep=Bp5ccxwBzLlAG0%2FH6Ajc9BK2CHGLmE%2FI6YrkNt1v%2FiSiMqPqcylWvjS%2BJqkjN%2BP0ZzFvyk5pKqrRS1WSpdbnHJUPMfc3tDsJUJSOPVINsHf9OlYhsfDP2VDSqqnS&ctype=86&K=768415ccc619f0ae24129688&yxon=1&ev=1&token=2412
[DEBUG] get_content: http://k.youku.com/player/getFlvPath/sid/946182150401686da3f3a_00/st/flv/fileid/0300010B0457203D92EA8F2D9B7D2F561017A4-4E51-68F3-B5BC-23EBF9BBC4EF?oip=1176176655&ep=Bp5ccxwBzLlAG0%2FH6Ajc9BK2CHGLmE%2FI6YrkNt1v%2FiOiMqPqcylWvjS%2BJqkjN%2BP0ZzFvyk5pKqrRS1WSpdbnHJUPMfc3tDsJUJSOPVINsHf9OlYhsfDP2VDSqqnS&ctype=86&K=0f4c8142e2146fd6282b5f3e&yxon=1&ev=1&token=2412
[DEBUG] get_content: http://k.youku.com/player/getFlvPath/sid/946182150401686da3f3a_00/st/flv/fileid/0300010B0557203D92EA8F2D9B7D2F561017A4-4E51-68F3-B5BC-23EBF9BBC4EF?oip=1176176655&ep=Bp5ccxwBzLlAG0%2FH6Ajc9BK2CHGLmE%2FI6YrkNt1v%2FiKiMqPqcylWvjS%2BJqkjN%2BP0ZzFvyk5pKqrRS1WSpdbnHJUPMfc3tDsJUJSOPVINsHf9OlYhsfDP2VDSqqnS&ctype=86&K=a063d082ee92e290282b5f3e&yxon=1&ev=1&token=2412
[DEBUG] get_content: http://k.youku.com/player/getFlvPath/sid/946182150401686da3f3a_00/st/flv/fileid/0300010B0657203D92EA8F2D9B7D2F561017A4-4E51-68F3-B5BC-23EBF9BBC4EF?oip=1176176655&ep=Bp5ccxwBzLlAG0%2FH6Ajc9BK2CHGLmE%2FI6YrkNt1v%2FiGiMqPqcylWvjS%2BJqkjN%2BP0ZzFvyk5pKqrRS1WSpdbnHJUPMfc3tDsJUJSOPVINsHf9OlYhsfDP2VDSqqnS&ctype=86&K=5e26320e138989f1261efae3&yxon=1&ev=1&token=2412
[DEBUG] get_content: http://k.youku.com/player/getFlvPath/sid/946182150401686da3f3a_00/st/flv/fileid/0300010B0757203D92EA8F2D9B7D2F561017A4-4E51-68F3-B5BC-23EBF9BBC4EF?oip=1176176655&ep=Bp5ccxwBzLlAG0%2FH6Ajc9BK2CHGLmE%2FI6YrkNt1v%2FiCiMqPqcylWvjS%2BJqkjN%2BP0ZzFvyk5pKqrRS1WSpdbnHJUPMfc3tDsJUJSOPVINsHf9OlYhsfDP2VDSqqnS&ctype=86&K=e93aa4c00e75bbaf282b5f3e&yxon=1&ev=1&token=2412
[DEBUG] get_content: http://k.youku.com/player/getFlvPath/sid/946182150401686da3f3a_00/st/flv/fileid/0300010B0857203D92EA8F2D9B7D2F561017A4-4E51-68F3-B5BC-23EBF9BBC4EF?oip=1176176655&ep=Bp5ccxwBzLlAG0%2FH6Ajc9BK2CHGLmE%2FI6YrkNt1v%2Fi%2BiMqPqcylWvjS%2BJqkjN%2BP0ZzFvyk5pKqrRS1WSpdbnHJUPMfc3tDsJUJSOPVINsHf9OlYhsfDP2VDSqqnS&ctype=86&K=25a3be5f1e829b20261efae3&yxon=1&ev=1&token=2412
[DEBUG] get_content: http://k.youku.com/player/getFlvPath/sid/946182150401686da3f3a_00/st/flv/fileid/0300010B0957203D92EA8F2D9B7D2F561017A4-4E51-68F3-B5BC-23EBF9BBC4EF?oip=1176176655&ep=Bp5ccxwBzLlAG0%2FH6Ajc9BK2CHGLmE%2FI6YrkNt1v%2Fi6iMqPqcylWvjS%2BJqkjN%2BP0ZzFvyk5pKqrRS1WSpdbnHJUPMfc3tDsJUJSOPVINsHf9OlYhsfDP2VDSqqnS&ctype=86&K=58d1c740228579b924129688&yxon=1&ev=1&token=2412
[DEBUG] get_content: http://k.youku.com/player/getFlvPath/sid/946182150401686da3f3a_00/st/flv/fileid/0300010B0A57203D92EA8F2D9B7D2F561017A4-4E51-68F3-B5BC-23EBF9BBC4EF?oip=1176176655&ep=Bp5ccxwBzLlAG0%2FH6Ajc9BK2CHGLmE%2FI6YrkNt1v%2FlaiMqPqcylWvjS%2BJqkjN%2BP0ZzFvyk5pKqrRS1WSpdbnHJUPMfc3tDsJUJSOPVINsHf9OlYhsfDP2VDSqqnS&ctype=86&K=3bc2288ce30f886b24129688&yxon=1&ev=1&token=2412
site:                优酷 (Youku)
title:               马猴烧酒变身第三期
streams:             # Available quality and codecs
    [ DEFAULT ] _________________________________
    - format:        hd2
      container:     flv
      video-profile: 超清
      size:          389.0 MiB (407922611 bytes)
    # download-with: you-get --format=hd2 [URL]

    - format:        mp4
      container:     mp4
      video-profile: 高清
      size:          223.9 MiB (234784857 bytes)
    # download-with: you-get --format=mp4 [URL]

    - format:        flvhd
      container:     flv
      video-profile: 标清
      size:          120.2 MiB (126072622 bytes)
    # download-with: you-get --format=flvhd [URL]

    - format:        3gphd
      container:     3gp
      video-profile: 标清（3GP）
      size:          99.5 MiB (104342150 bytes)
    # download-with: you-get --format=3gphd [URL]


```

Proof of not breaking something else:

```
$ python3 you-get -di http://v.youku.com/v_show/id_XMTU1MDY0MTg4MA==.html
[DEBUG] get_content: http://play.youku.com/play/get.json?vid=XMTU1MDY0MTg4MA==&ct=10
[DEBUG] get_content: http://play.youku.com/play/get.json?vid=XMTU1MDY0MTg4MA==&ct=12
[DEBUG] get_content: http://k.youku.com/player/getFlvPath/sid/146182110826612086532_00/st/flv/fileid/0300010100572158EEAE482FBE416E02DD9552-3701-5ECF-B0A2-6E41CB731195?ev=1&oip=1176176655&yxon=1&ep=cyaSG0GPV88A7SHZjj8bZyTkcXQNXP4J9h%2BFgNJjALshT%2Bq%2BnDaksuzFSvdAYItsdiMAZevz36Tub0UWYfNEqWkQ2jvbT%2FqS%2FoHh5asmwJFzFB41c8zesVSeSjP1&token=0934&K=8f7454d8aba2a1df24129688&ctype=12
[DEBUG] get_content: http://k.youku.com/player/getFlvPath/sid/146182110826612086532_00/st/flv/fileid/0300010100568BC189B4DD000032C8E64C9A66-35BF-D190-178B-E37C4F851173?ev=1&oip=1176176655&yxon=1&ep=cyaSG0GPV88A7SHZjj8bZyTkcXQNXP4J9h%2BFgNJjALshTuDN6j%2FZzu%2B0OotCFvkZcSB1GJ73r6PuG0YSYfNG2x4Qq0%2BhOfrh%2BfiR5dhQw%2BMEEBEzc8zQt1SeSjP1&token=0934&K=b13669cc4988e60b24129688&ctype=12
site:                优酷 (Youku)
title:               实拍3名和尚寺庙内打架 住持发朋友圈：全开除
streams:             # Available quality and codecs
    [ DEFAULT ] _________________________________
    - format:        hd2
      container:     flv
      video-profile: 超清
      size:          13.9 MiB (14586247 bytes)
    # download-with: you-get --format=hd2 [URL]

    - format:        mp4
      container:     mp4
      video-profile: 高清
      size:          7.6 MiB (7951724 bytes)
    # download-with: you-get --format=mp4 [URL]

    - format:        flvhd
      container:     flv
      video-profile: 标清
      size:          3.9 MiB (4114669 bytes)
    # download-with: you-get --format=flvhd [URL]
```

<!-- Reviewable:start -->

---

This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/soimort/you-get/1089)

<!-- Reviewable:end -->
