forked from tpd94/CDRM-Project
		
	Updates
- Added virtual environment (venv) check - Added pip check - Added minimum python version check - Added requirements.txt check - Added proxy support for front/back end - Added opengraph images for each url - Added pyinstaller support
This commit is contained in:
		
							parent
							
								
									525624cdf1
								
							
						
					
					
						commit
						2095a5b668
					
				
							
								
								
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -3,4 +3,7 @@
 | 
			
		||||
*.wvd
 | 
			
		||||
*.db
 | 
			
		||||
.idea/
 | 
			
		||||
configs/config.yaml
 | 
			
		||||
configs/config.yaml
 | 
			
		||||
build
 | 
			
		||||
main.spec
 | 
			
		||||
pyinstallericon.ico
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								cdrm-frontend/dist/index.html
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								cdrm-frontend/dist/index.html
									
									
									
									
										vendored
									
									
								
							@ -12,7 +12,7 @@
 | 
			
		||||
    <meta property='og:url' content="{{ data.opengraph_url }}" />
 | 
			
		||||
    <meta property='og:locale' content='en_US' />
 | 
			
		||||
    <title>{{ data.tab_title }}</title>
 | 
			
		||||
    <script type="module" crossorigin src="/assets/index-bTy8Pcga.js"></script>
 | 
			
		||||
    <script type="module" crossorigin src="/assets/index-D2On2KQO.js"></script>
 | 
			
		||||
    <link rel="stylesheet" crossorigin href="/assets/index-0Rv9u7Qs.css">
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 1.4 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								cdrm-frontend/public/og-api.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								cdrm-frontend/public/og-api.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 189 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								cdrm-frontend/public/og-cache.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								cdrm-frontend/public/og-cache.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 207 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								cdrm-frontend/public/og-home.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								cdrm-frontend/public/og-home.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 302 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								cdrm-frontend/public/og-testplayer.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								cdrm-frontend/public/og-testplayer.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 99 KiB  | 
@ -30,6 +30,7 @@ function Home() {
 | 
			
		||||
  const handleSubmitButton = (event) => {
 | 
			
		||||
    let pssh = document.getElementById('pssh').value;
 | 
			
		||||
    let licurl = document.getElementById('licurl').value;
 | 
			
		||||
    let proxy = document.getElementById('proxy').value;
 | 
			
		||||
    let headers = document.getElementById('headers').value;
 | 
			
		||||
    let cookies = document.getElementById('cookies').value;
 | 
			
		||||
    let data = document.getElementById('data').value;
 | 
			
		||||
@ -42,6 +43,7 @@ function Home() {
 | 
			
		||||
      body: JSON.stringify({
 | 
			
		||||
        pssh: pssh,
 | 
			
		||||
        licurl: licurl,
 | 
			
		||||
        proxy: proxy,
 | 
			
		||||
        headers: headers,
 | 
			
		||||
        cookies: cookies,
 | 
			
		||||
        data: data
 | 
			
		||||
@ -64,6 +66,7 @@ function Home() {
 | 
			
		||||
  const handleResetButton = (event) => {
 | 
			
		||||
    let pssh = document.getElementById('pssh');
 | 
			
		||||
    let licurl = document.getElementById('licurl');
 | 
			
		||||
    let proxy = document.getElementById('proxy');
 | 
			
		||||
    let headers = document.getElementById('headers');
 | 
			
		||||
    let cookies = document.getElementById('cookies');
 | 
			
		||||
    let data = document.getElementById('data');
 | 
			
		||||
@ -94,6 +97,8 @@ function Home() {
 | 
			
		||||
          <input type='text' id='pssh' name='pssh' className='text-white bg-[rgba(0,0,0,0.2)] focus:outline-none rounded focus:shadow-sm focus:shadow-cyan-500/50 transition-shadow duration-300 ease-in-out p-2' />
 | 
			
		||||
          <label htmlFor='licurl' className='text-white mb-1 mt-1'>License URL:</label>
 | 
			
		||||
          <input type='text' id='licurl' name='licurl' className='text-white bg-[rgba(0,0,0,0.2)] focus:outline-none rounded focus:shadow-sm focus:shadow-cyan-500/50 transition-shadow duration-300 ease-in-out p-2' />
 | 
			
		||||
          <label htmlFor='proxy' className='text-white mb-1 mt-1'>Proxy:</label>
 | 
			
		||||
          <input type='text' id='proxy' name='proxy' className='text-white bg-[rgba(0,0,0,0.2)] focus:outline-none rounded focus:shadow-sm focus:shadow-cyan-500/50 transition-shadow duration-300 ease-in-out p-2' />
 | 
			
		||||
          <label htmlFor='headers' className='text-white mb-1 mt-1'>Headers:</label>
 | 
			
		||||
          <textarea id='headers' name='headers' className='text-white bg-[rgba(0,0,0,0.2)] h-24 focus:h-92 focus:outline-none rounded focus:shadow-sm focus:shadow-cyan-500/50 transition-all duration-300 ease-in-out p-2 resize-none' />
 | 
			
		||||
          <label htmlFor='cookies' className='text-white mb-1 mt-1'>Cookies:</label>
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ tags = {
 | 
			
		||||
        'keywords': 'CDRM, Widevine, PlayReady, DRM, Decrypt, CDM, CDM-Project, CDRM-Project, TPD94, Decryption',
 | 
			
		||||
        'opengraph_title': 'CDRM-Project',
 | 
			
		||||
        'opengraph_description': 'Self Hosted web application written in Python/JavaScript utilizing the Flask/Tailwind Framework and ReactJS library to decrypt Widevine & Playready content',
 | 
			
		||||
        'opengraph_image': 'https://cdrm-project.com/lockforog.png',
 | 
			
		||||
        'opengraph_image': 'https://cdrm-project.com/og-home.jpg',
 | 
			
		||||
        'opengraph_url': 'https://cdm-project.com/tpd94/cdrm-project',
 | 
			
		||||
        'tab_title': 'CDRM-Project',
 | 
			
		||||
    },
 | 
			
		||||
@ -13,7 +13,7 @@ tags = {
 | 
			
		||||
        'keywords': 'Cache, Vault, Widevine, PlayReady, DRM, Decryption, CDM, CDRM-Project, CDRM-Project, TPD94, Decryption',
 | 
			
		||||
        'opengraph_title': 'Search the Cache',
 | 
			
		||||
        'opengraph_description': 'Search the cache by KID or PSSH for decryption keys',
 | 
			
		||||
        'opengraph_image': 'https://cdrm-project.com/lockforog.png',
 | 
			
		||||
        'opengraph_image': 'https://cdrm-project.com/og-cache.jpg',
 | 
			
		||||
        'opengraph_url': 'https://cdrm-project.com/cache',
 | 
			
		||||
        'tab_title': 'Cache',
 | 
			
		||||
    },
 | 
			
		||||
@ -22,7 +22,7 @@ tags = {
 | 
			
		||||
        'keywords': 'Shaka, Player, DRM, CDRM, CDM, CDRM-Project, TPD94, Decryption, CDM-Project, KID, KEY',
 | 
			
		||||
        'opengraph_title': 'Test Player',
 | 
			
		||||
        'opengraph_description': 'Shaka Player for testing decryption keys',
 | 
			
		||||
        'opengraph_image': 'https://cdrm-project.com/lockforog.png',
 | 
			
		||||
        'opengraph_image': 'https://cdrm-project.com/og-testplayer.jpg',
 | 
			
		||||
        'opengraph_url': 'https://cdrm-project.com/testplayer',
 | 
			
		||||
        'tab_title': 'Test Player',
 | 
			
		||||
    },
 | 
			
		||||
@ -31,7 +31,7 @@ tags = {
 | 
			
		||||
        'keywords': 'API, python, requests, send, remotecdm, remote, cdm, CDM-Project, CDRM-Project, TPD94, Decryption, DRM, Web, Vault',
 | 
			
		||||
        'opengraph_title': 'API',
 | 
			
		||||
        'opengraph_description': 'Documentation for the program "CDRM-Project"',
 | 
			
		||||
        'opengraph_image': 'https://cdrm-project.com/lockforog.png',
 | 
			
		||||
        'opengraph_image': 'https://cdrm-project.com/og-api.jpg',
 | 
			
		||||
        'opengraph_url': 'https://cdrm-project.com/api',
 | 
			
		||||
        'tab_title': 'API',
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@ import ast
 | 
			
		||||
import glob
 | 
			
		||||
import os
 | 
			
		||||
import yaml
 | 
			
		||||
 | 
			
		||||
from urllib.parse import urlparse
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -73,7 +73,18 @@ def is_base64(string):
 | 
			
		||||
        # If decoding or encoding fails, it's not Base64
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
def api_decrypt(pssh:str = None, license_url: str = None, headers: str = None, cookies: str = None, json_data: str = None):
 | 
			
		||||
def is_url_and_split(input_str):
 | 
			
		||||
    parsed = urlparse(input_str)
 | 
			
		||||
 | 
			
		||||
    # Check if it's a valid URL with scheme and netloc
 | 
			
		||||
    if parsed.scheme and parsed.netloc:
 | 
			
		||||
        protocol = parsed.scheme
 | 
			
		||||
        fqdn = parsed.netloc
 | 
			
		||||
        return True, protocol, fqdn
 | 
			
		||||
    else:
 | 
			
		||||
        return False, None, None
 | 
			
		||||
 | 
			
		||||
def api_decrypt(pssh:str = None, license_url: str = None, proxy: str = None, headers: str = None, cookies: str = None, json_data: str = None):
 | 
			
		||||
    with open(f'{os.getcwd()}/configs/config.yaml', 'r') as file:
 | 
			
		||||
        config = yaml.safe_load(file)
 | 
			
		||||
    if config['database_type'].lower() == 'sqlite':
 | 
			
		||||
@ -165,14 +176,30 @@ def api_decrypt(pssh:str = None, license_url: str = None, headers: str = None, c
 | 
			
		||||
                    'message': f'An error occurred getting json_data\n\n{error}'
 | 
			
		||||
                }
 | 
			
		||||
            licence = None
 | 
			
		||||
            proxies = None
 | 
			
		||||
            if proxy is not None:
 | 
			
		||||
                is_url, protocol, fqdn = is_url_and_split(proxy)
 | 
			
		||||
                if is_url:
 | 
			
		||||
                    proxies = {'http': proxy, 'https': proxy}
 | 
			
		||||
                else:
 | 
			
		||||
                    return {
 | 
			
		||||
                        'status': 'error',
 | 
			
		||||
                        'message': f'Your proxy is invalid, please put it in the format of http(s)://fqdn.tld:port'
 | 
			
		||||
                    }
 | 
			
		||||
            try:
 | 
			
		||||
                licence = requests.post(
 | 
			
		||||
                    url=license_url,
 | 
			
		||||
                    headers=format_headers,
 | 
			
		||||
                    proxies=proxies,
 | 
			
		||||
                    cookies=format_cookies,
 | 
			
		||||
                    json=format_json_data if format_json_data is not None else None,
 | 
			
		||||
                    data=pr_challenge if format_json_data is None else None
 | 
			
		||||
                )
 | 
			
		||||
            except requests.exceptions.ConnectionError as error:
 | 
			
		||||
                return {
 | 
			
		||||
                    'status': 'error',
 | 
			
		||||
                    'message': f'An error occurred sending license challenge through your proxy\n\n{error}'
 | 
			
		||||
                }
 | 
			
		||||
            except Exception as error:
 | 
			
		||||
                return {
 | 
			
		||||
                    'status': 'error',
 | 
			
		||||
@ -310,14 +337,25 @@ def api_decrypt(pssh:str = None, license_url: str = None, headers: str = None, c
 | 
			
		||||
                'message': f'An error occurred getting json_data\n\n{error}'
 | 
			
		||||
            }
 | 
			
		||||
        licence = None
 | 
			
		||||
        proxies = None
 | 
			
		||||
        if proxy is not None:
 | 
			
		||||
            is_url, protocol, fqdn = is_url_and_split(proxy)
 | 
			
		||||
            if is_url:
 | 
			
		||||
                proxies = {'http': proxy, 'https': proxy}
 | 
			
		||||
        try:
 | 
			
		||||
            licence = requests.post(
 | 
			
		||||
                url=license_url,
 | 
			
		||||
                headers=format_headers,
 | 
			
		||||
                proxies=proxies,
 | 
			
		||||
                cookies=format_cookies,
 | 
			
		||||
                json=format_json_data if format_json_data is not None else None,
 | 
			
		||||
                data=wv_challenge if format_json_data is None else None
 | 
			
		||||
            )
 | 
			
		||||
        except requests.exceptions.ConnectionError as error:
 | 
			
		||||
            return {
 | 
			
		||||
                'status': 'error',
 | 
			
		||||
                'message': f'An error occurred sending license challenge through your proxy\n\n{error}'
 | 
			
		||||
            }
 | 
			
		||||
        except Exception as error:
 | 
			
		||||
            return {
 | 
			
		||||
                'status': 'error',
 | 
			
		||||
 | 
			
		||||
@ -77,6 +77,8 @@ def requirements_check():
 | 
			
		||||
                print("Invalid input. Please enter 'Y' to install or 'N' to exit.")
 | 
			
		||||
 | 
			
		||||
def run_python_checks():
 | 
			
		||||
    if getattr(sys, 'frozen', False):  # Check if running from PyInstaller
 | 
			
		||||
        return
 | 
			
		||||
    version_check()
 | 
			
		||||
    pip_check()
 | 
			
		||||
    venv_check()
 | 
			
		||||
 | 
			
		||||
@ -195,6 +195,13 @@ def decrypt_data():
 | 
			
		||||
            api_request_licurl = api_request_data['licurl']
 | 
			
		||||
    else:
 | 
			
		||||
        api_request_licurl = None
 | 
			
		||||
    if 'proxy' in api_request_data:
 | 
			
		||||
        if api_request_data['proxy'] == '':
 | 
			
		||||
            api_request_proxy = None
 | 
			
		||||
        else:
 | 
			
		||||
            api_request_proxy = api_request_data['proxy']
 | 
			
		||||
    else:
 | 
			
		||||
        api_request_proxy = None
 | 
			
		||||
    if 'headers' in api_request_data:
 | 
			
		||||
        if api_request_data['headers'] == '':
 | 
			
		||||
            api_request_headers = None
 | 
			
		||||
@ -216,7 +223,7 @@ def decrypt_data():
 | 
			
		||||
            api_request_data = api_request_data['data']
 | 
			
		||||
    else:
 | 
			
		||||
        api_request_data = None
 | 
			
		||||
    result = api_decrypt(pssh=api_request_pssh, license_url=api_request_licurl, headers=api_request_headers, cookies=api_request_cookies, json_data=api_request_data)
 | 
			
		||||
    result = api_decrypt(pssh=api_request_pssh, proxy=api_request_proxy, license_url=api_request_licurl, headers=api_request_headers, cookies=api_request_cookies, json_data=api_request_data)
 | 
			
		||||
    if result['status'] == 'success':
 | 
			
		||||
        return jsonify({
 | 
			
		||||
            'status': 'success',
 | 
			
		||||
 | 
			
		||||
@ -1,30 +1,33 @@
 | 
			
		||||
from flask import Blueprint, send_from_directory, request, render_template
 | 
			
		||||
import sys
 | 
			
		||||
import os
 | 
			
		||||
from flask import Blueprint, send_from_directory, request, render_template
 | 
			
		||||
from configs import index_tags
 | 
			
		||||
 | 
			
		||||
react_bp = Blueprint('react_bp', __name__, static_folder=f'{os.getcwd()}/cdrm-frontend/dist', static_url_path='/',
 | 
			
		||||
                     template_folder=f'{os.getcwd()}/cdrm-frontend/dist')
 | 
			
		||||
if getattr(sys, 'frozen', False):  # Running as a bundled app
 | 
			
		||||
    base_path = sys._MEIPASS
 | 
			
		||||
else:  # Running in a normal Python environment
 | 
			
		||||
    base_path = os.path.abspath(".")
 | 
			
		||||
 | 
			
		||||
static_folder = os.path.join(base_path, 'cdrm-frontend', 'dist')
 | 
			
		||||
 | 
			
		||||
react_bp = Blueprint(
 | 
			
		||||
    'react_bp',
 | 
			
		||||
    __name__,
 | 
			
		||||
    static_folder=static_folder,
 | 
			
		||||
    static_url_path='/',
 | 
			
		||||
    template_folder=static_folder
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@react_bp.route('/', methods=['GET'])
 | 
			
		||||
@react_bp.route('/<path:path>', methods=["GET"])
 | 
			
		||||
@react_bp.route('/<path>', methods=["GET"])
 | 
			
		||||
def index(path=''):
 | 
			
		||||
    if request.method == 'GET':
 | 
			
		||||
        if path != "" and os.path.exists(react_bp.static_folder + '/' + path):
 | 
			
		||||
        file_path = os.path.join(react_bp.static_folder, path)
 | 
			
		||||
        if path != "" and os.path.exists(file_path):
 | 
			
		||||
            return send_from_directory(react_bp.static_folder, path)
 | 
			
		||||
        elif path.lower() == '':
 | 
			
		||||
            data = index_tags.tags['index']
 | 
			
		||||
            return render_template('index.html', data=data)
 | 
			
		||||
        elif path.lower() == 'cache':
 | 
			
		||||
            data = index_tags.tags['cache']
 | 
			
		||||
            return render_template('index.html', data=data)
 | 
			
		||||
        elif path.lower() == 'api':
 | 
			
		||||
            data = index_tags.tags['api']
 | 
			
		||||
            return render_template('index.html', data=data)
 | 
			
		||||
        elif path.lower() == 'testplayer':
 | 
			
		||||
            data = index_tags.tags['test_player']
 | 
			
		||||
        elif path.lower() in ['', 'cache', 'api', 'testplayer']:
 | 
			
		||||
            data = index_tags.tags.get(path.lower(), index_tags.tags['index'])
 | 
			
		||||
            return render_template('index.html', data=data)
 | 
			
		||||
        else:
 | 
			
		||||
            return send_from_directory(react_bp.static_folder, 'index.html')
 | 
			
		||||
    else:
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user