forked from tpd94/CDRM-Project
		
	<head> templating
- Added Jinja2 templating to index.html for dynamic opengraph, tags, titles, and descriptions for bots via flask's render_template - Added index_tags.py to config folder for easily edited information for the update above - Added helmet to react to dynamically change the title of the tab for dynamic tabs even after a static index.html has been served by flask's render template
This commit is contained in:
		
							parent
							
								
									27184f0abd
								
							
						
					
					
						commit
						525624cdf1
					
				
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										16
									
								
								cdrm-frontend/dist/index.html
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								cdrm-frontend/dist/index.html
									
									
									
									
										vendored
									
									
								
							@ -4,15 +4,15 @@
 | 
			
		||||
    <meta charset="UTF-8" />
 | 
			
		||||
    <link rel="icon" type="image/svg+xml" href="/favico.png" />
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 | 
			
		||||
    <meta name="description" content="Decrypt Widevine and PlayReady protected content." />
 | 
			
		||||
    <meta name="keywords" content="CDRM, Widevine, PlayReady, DRM, Decrypt, CDM, CDM-Project, CDRM-Project, TPD94, Decryption" />
 | 
			
		||||
    <meta property='og:title' content='CDRM-Project' />
 | 
			
		||||
    <meta property='og:description' content='Decrypt Widevine & PlayReady Content' />
 | 
			
		||||
    <meta property='og:image' content='https://cdrm-project.com/lockforog.png' />
 | 
			
		||||
    <meta property='og:url' content='https://cdrm-project.com/' />
 | 
			
		||||
    <meta name="description" content="{{ data.description }}"/>
 | 
			
		||||
    <meta name="keywords" content="{{ data.keywords }}"/>
 | 
			
		||||
    <meta property='og:title' content="{{ data.opengraph_title }}" />
 | 
			
		||||
    <meta property='og:description' content="{{ data.opengraph_description }}" />
 | 
			
		||||
    <meta property='og:image' content="{{ data.opengraph_image }}" />
 | 
			
		||||
    <meta property='og:url' content="{{ data.opengraph_url }}" />
 | 
			
		||||
    <meta property='og:locale' content='en_US' />
 | 
			
		||||
    <title>CDRM-Project</title>
 | 
			
		||||
    <script type="module" crossorigin src="/assets/index-BCBsxJZZ.js"></script>
 | 
			
		||||
    <title>{{ data.tab_title }}</title>
 | 
			
		||||
    <script type="module" crossorigin src="/assets/index-bTy8Pcga.js"></script>
 | 
			
		||||
    <link rel="stylesheet" crossorigin href="/assets/index-0Rv9u7Qs.css">
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
 | 
			
		||||
@ -4,14 +4,14 @@
 | 
			
		||||
    <meta charset="UTF-8" />
 | 
			
		||||
    <link rel="icon" type="image/svg+xml" href="/favico.png" />
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 | 
			
		||||
    <meta name="description" content="Decrypt Widevine and PlayReady protected content." />
 | 
			
		||||
    <meta name="keywords" content="CDRM, Widevine, PlayReady, DRM, Decrypt, CDM, CDM-Project, CDRM-Project, TPD94, Decryption" />
 | 
			
		||||
    <meta property='og:title' content='CDRM-Project' />
 | 
			
		||||
    <meta property='og:description' content='Decrypt Widevine & PlayReady Content' />
 | 
			
		||||
    <meta property='og:image' content='https://cdrm-project.com/lockforog.png' />
 | 
			
		||||
    <meta property='og:url' content='https://cdrm-project.com/' />
 | 
			
		||||
    <meta name="description" content="{{ data.description }}"/>
 | 
			
		||||
    <meta name="keywords" content="{{ data.keywords }}"/>
 | 
			
		||||
    <meta property='og:title' content="{{ data.opengraph_title }}" />
 | 
			
		||||
    <meta property='og:description' content="{{ data.opengraph_description }}" />
 | 
			
		||||
    <meta property='og:image' content="{{ data.opengraph_image }}" />
 | 
			
		||||
    <meta property='og:url' content="{{ data.opengraph_url }}" />
 | 
			
		||||
    <meta property='og:locale' content='en_US' />
 | 
			
		||||
    <title>CDRM-Project</title>
 | 
			
		||||
    <title>{{ data.tab_title }}</title>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div id="root"></div>
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
import React, { useState, useEffect } from 'react';
 | 
			
		||||
import { data } from 'react-router-dom';
 | 
			
		||||
const { protocol, hostname, port } = window.location;
 | 
			
		||||
import { Helmet } from 'react-helmet';
 | 
			
		||||
 | 
			
		||||
let fullHost = `${protocol}//${hostname}`;
 | 
			
		||||
if (
 | 
			
		||||
@ -62,6 +63,9 @@ function API() {
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <div className='min-w-full w-full min-h-full overflow-x-auto bg-zinc-900 shadow-lg shadow-black flex flex-col flex-wrap p-10 justify-around'>
 | 
			
		||||
      <Helmet>
 | 
			
		||||
        <title>API</title>
 | 
			
		||||
      </Helmet>
 | 
			
		||||
        
 | 
			
		||||
        {/* Decryption Request Section */}
 | 
			
		||||
        <details open className='p-5 mb-5 border shadow-lg shadow-black overflow-y-auto'>
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
import React, { useState, useEffect, useRef } from 'react';
 | 
			
		||||
import { Helmet } from 'react-helmet';
 | 
			
		||||
 | 
			
		||||
function Cache() {
 | 
			
		||||
  const [searchQuery, setSearchQuery] = useState('');
 | 
			
		||||
@ -57,6 +58,9 @@ function Cache() {
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <div className='w-full h-full bg-zinc-900 flex flex-col p-0'>
 | 
			
		||||
      <Helmet>
 | 
			
		||||
        <title>Cache</title>
 | 
			
		||||
      </Helmet>
 | 
			
		||||
        <div className='flex flex-row w-full'>
 | 
			
		||||
          <form className='flex flex-row w-8/10 p-10 h-full rounded-xl self-start'>
 | 
			
		||||
            <input
 | 
			
		||||
 | 
			
		||||
@ -86,6 +86,9 @@ function Home() {
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <div className='w-full min-h-full bg-zinc-900 flex flex-col items-center justify-center'>
 | 
			
		||||
      <Helmet>
 | 
			
		||||
        <title>CDRM-Project</title>
 | 
			
		||||
      </Helmet>
 | 
			
		||||
        <form className='flex flex-col w-8/10 min-h-8/10 bg-[rgba(0,0,0,0.2)] p-10 border-black border-1 rounded-xl shadow-lg shadow-cyan-500/50 overflow-y-auto' onSubmit={handleSubmit}>
 | 
			
		||||
          <label htmlFor='pssh' className='text-white mb-1'>PSSH:</label>
 | 
			
		||||
          <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' />
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
import React, { useState, useRef } from "react";
 | 
			
		||||
import shaka from "shaka-player"; // Import the Shaka Player library
 | 
			
		||||
import { Helmet } from 'react-helmet';
 | 
			
		||||
 | 
			
		||||
function TestPlayer() {
 | 
			
		||||
  const [mpdUrl, setMpdUrl] = useState("");
 | 
			
		||||
@ -53,6 +54,9 @@ function TestPlayer() {
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="min-w-full w-full min-h-full h-full bg-zinc-900 shadow-lg shadow-black flex flex-row overflow-y-auto pt-5 pl-5 pr-5 items-center justify-around">
 | 
			
		||||
      <Helmet>
 | 
			
		||||
        <title>Test Player</title>
 | 
			
		||||
      </Helmet>
 | 
			
		||||
      <div className="min-8/10 w-8/10 min-h-8/10 h-8/10 flex flex-row overflow-y-auto items-center justify-around border shadow-lg shadow-red-700 rounded-2xl">
 | 
			
		||||
        <div className="w-7/10 h-7/10 border border-black rounded-2xl p-5 bg-[rgba(0,0,0,0.2)] shadow-lg shadow-black">
 | 
			
		||||
          <video
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										38
									
								
								configs/index_tags.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								configs/index_tags.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,38 @@
 | 
			
		||||
tags = {
 | 
			
		||||
    'index': {
 | 
			
		||||
        'description': 'Decrypt Widevine and PlayReady protected content',
 | 
			
		||||
        '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_url': 'https://cdm-project.com/tpd94/cdrm-project',
 | 
			
		||||
        'tab_title': 'CDRM-Project',
 | 
			
		||||
    },
 | 
			
		||||
    'cache': {
 | 
			
		||||
        'description': 'Search the cache by KID or PSSH for decryption keys',
 | 
			
		||||
        '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_url': 'https://cdrm-project.com/cache',
 | 
			
		||||
        'tab_title': 'Cache',
 | 
			
		||||
    },
 | 
			
		||||
    'test_player': {
 | 
			
		||||
        'description': 'Shaka Player for testing decryption keys',
 | 
			
		||||
        '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_url': 'https://cdrm-project.com/testplayer',
 | 
			
		||||
        'tab_title': 'Test Player',
 | 
			
		||||
    },
 | 
			
		||||
    'api': {
 | 
			
		||||
        'description': 'API documentation for the program "CDRM-Project"',
 | 
			
		||||
        '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_url': 'https://cdrm-project.com/api',
 | 
			
		||||
        'tab_title': 'API',
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										83
									
								
								custom_functions/prechecks/python_checks.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								custom_functions/prechecks/python_checks.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,83 @@
 | 
			
		||||
import sys
 | 
			
		||||
import os
 | 
			
		||||
import subprocess
 | 
			
		||||
import venv
 | 
			
		||||
 | 
			
		||||
def version_check():
 | 
			
		||||
    major_version = sys.version_info.major
 | 
			
		||||
    minor_version = sys.version_info.minor
 | 
			
		||||
 | 
			
		||||
    if major_version >= 3:
 | 
			
		||||
        if minor_version >= 13:
 | 
			
		||||
            return
 | 
			
		||||
        else:
 | 
			
		||||
            exit("Python version 3.13 or higher is required")
 | 
			
		||||
    else:
 | 
			
		||||
        exit("Python 2 detected, Python version 3.13 or higher is required")
 | 
			
		||||
 | 
			
		||||
def pip_check():
 | 
			
		||||
    try:
 | 
			
		||||
        import pip
 | 
			
		||||
        return
 | 
			
		||||
    except ImportError:
 | 
			
		||||
        exit("Pip is not installed")
 | 
			
		||||
 | 
			
		||||
def venv_check():
 | 
			
		||||
    # Check if we're already inside a virtual environment
 | 
			
		||||
    if hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix):
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    venv_path = os.path.join(os.getcwd(), 'cdrm-venv')
 | 
			
		||||
    venv_python = os.path.join(venv_path, 'bin', 'python') if os.name != 'nt' else os.path.join(venv_path, 'Scripts', 'python.exe')
 | 
			
		||||
 | 
			
		||||
    # If venv already exists, restart script using its Python
 | 
			
		||||
    if os.path.exists(venv_path):
 | 
			
		||||
        subprocess.call([venv_python] + sys.argv)
 | 
			
		||||
        sys.exit()
 | 
			
		||||
 | 
			
		||||
    # Ask user for permission to create a virtual environment
 | 
			
		||||
    answer = ''
 | 
			
		||||
    while not answer or answer[0].upper() not in {'Y', 'N'}:
 | 
			
		||||
        answer = input(
 | 
			
		||||
            'Program is not running from a venv. To maintain compatibility and dependencies, this program must be run from one.\n'
 | 
			
		||||
            'Would you like me to create one for you? (Y/N): '
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    if answer[0].upper() == 'Y':
 | 
			
		||||
        print("Creating virtual environment...")
 | 
			
		||||
        venv.create(venv_path, with_pip=True)
 | 
			
		||||
        subprocess.call([venv_python] + sys.argv)
 | 
			
		||||
        sys.exit()
 | 
			
		||||
    else:
 | 
			
		||||
        print("Exiting program. Please run it from a virtual environment next time.")
 | 
			
		||||
        sys.exit(1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def requirements_check():
 | 
			
		||||
    try:
 | 
			
		||||
        import pywidevine
 | 
			
		||||
        import pyplayready
 | 
			
		||||
        import flask
 | 
			
		||||
        import flask_cors
 | 
			
		||||
        import yaml
 | 
			
		||||
        import mysql.connector
 | 
			
		||||
        return
 | 
			
		||||
    except ImportError:
 | 
			
		||||
        while True:
 | 
			
		||||
            user_input = input("Missing packages. Do you want to install them? (Y/N): ").strip().upper()
 | 
			
		||||
            if user_input == 'Y':
 | 
			
		||||
                print("Installing packages from requirements.txt...")
 | 
			
		||||
                subprocess.check_call([sys.executable, "-m", "pip", "install", "-r", "requirements.txt"])
 | 
			
		||||
                print("Installation complete.")
 | 
			
		||||
                break
 | 
			
		||||
            elif user_input == 'N':
 | 
			
		||||
                print("Dependencies required, please install them and run again.")
 | 
			
		||||
                sys.exit()
 | 
			
		||||
            else:
 | 
			
		||||
                print("Invalid input. Please enter 'Y' to install or 'N' to exit.")
 | 
			
		||||
 | 
			
		||||
def run_python_checks():
 | 
			
		||||
    version_check()
 | 
			
		||||
    pip_check()
 | 
			
		||||
    venv_check()
 | 
			
		||||
    requirements_check()
 | 
			
		||||
							
								
								
									
										2
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								main.py
									
									
									
									
									
								
							@ -1,3 +1,5 @@
 | 
			
		||||
from custom_functions.prechecks.python_checks import run_python_checks
 | 
			
		||||
run_python_checks()
 | 
			
		||||
from custom_functions.prechecks.precheck import run_precheck
 | 
			
		||||
run_precheck()
 | 
			
		||||
from flask import Flask
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "CDRM-Project",
 | 
			
		||||
  "lockfileVersion": 3,
 | 
			
		||||
  "requires": true,
 | 
			
		||||
  "packages": {}
 | 
			
		||||
}
 | 
			
		||||
@ -1,7 +1,9 @@
 | 
			
		||||
from flask import Blueprint, send_from_directory, request
 | 
			
		||||
from flask import Blueprint, send_from_directory, request, render_template
 | 
			
		||||
import os
 | 
			
		||||
from configs import index_tags
 | 
			
		||||
 | 
			
		||||
react_bp = Blueprint('react_bp', __name__, static_folder=f'{os.getcwd()}/cdrm-frontend/dist', static_url_path='/')
 | 
			
		||||
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')
 | 
			
		||||
 | 
			
		||||
@react_bp.route('/', methods=['GET'])
 | 
			
		||||
@react_bp.route('/<path:path>', methods=["GET"])
 | 
			
		||||
@ -10,6 +12,18 @@ def index(path=''):
 | 
			
		||||
    if request.method == 'GET':
 | 
			
		||||
        if path != "" and os.path.exists(react_bp.static_folder + '/' + 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']
 | 
			
		||||
            return render_template('index.html', data=data)
 | 
			
		||||
        else:
 | 
			
		||||
            return send_from_directory(react_bp.static_folder, 'index.html')
 | 
			
		||||
    else:
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user