Skip to content

Commit

Permalink
Merge pull request #113 from DeckThemes/dev
Browse files Browse the repository at this point in the history
V2.1.0 - curse you valve
  • Loading branch information
suchmememanyskill authored Mar 14, 2024
2 parents d7a7887 + f5f1e8d commit 2e5920b
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 5,007 deletions.
44 changes: 40 additions & 4 deletions css_inject.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,45 @@
import json
import re
import os
import aiohttp
import asyncio
from typing import List
from css_utils import Result, Log
from css_utils import Result, Log, store_read, get_theme_path
from css_browserhook import BrowserTabHook as CssTab, inject, remove
import uuid

CLASS_MAPPINGS = {}

def initialize_class_mappings():
css_translations_path = os.path.join(get_theme_path(), "css_translations.json")

if not os.path.exists(css_translations_path):
Log("Failed to get css translations from local file")
return

try:
with open(css_translations_path, "r", encoding="utf-8") as fp:
data : dict = json.load(fp)
except Exception as e:
Log(f"Failed to load css translations from local file: {str(e)}")
return

CLASS_MAPPINGS.clear()

# Data is in the format of { "uid": ["ver1", "ver2", "ver3"]}
for uid in data:
latest_value = data[uid][-1]
for y in data[uid][:-1]:
CLASS_MAPPINGS[y] = latest_value

Log("Loaded css translations from local file")

ALL_INJECTS = []

def helper_get_tab_from_list(tab_list : List[str], cssTab : CssTab) -> str|None:
for x in tab_list:
if cssTab.compare(x):
return x

return None

class Inject:
Expand All @@ -28,8 +58,14 @@ async def load(self) -> Result:
with open(self.cssPath, "r") as fp:
self.css = fp.read()

split_css = re.split(r"(\.[_a-zA-Z]+[_a-zA-Z0-9-]*)", self.css)

for x in range(len(split_css)):
if split_css[x].startswith(".") and split_css[x][1:] in CLASS_MAPPINGS:
split_css[x] = "." + CLASS_MAPPINGS[split_css[x][1:]]

self.css = ("".join(split_css)).replace("\\", "\\\\").replace("`", "\\`")
Log(f"Loaded css at {self.cssPath}")
self.css = self.css.replace("\\", "\\\\").replace("`", "\\`")

return Result(True)
except Exception as e:
Expand Down
12 changes: 12 additions & 0 deletions css_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from css_theme import Theme, CSS_LOADER_VER
from css_themepatch import ThemePatch
from css_browserhook import remove_all, commit_all
from css_remoteinstall import upload

from asyncio import sleep
from os import listdir, path, mkdir
Expand Down Expand Up @@ -171,6 +172,17 @@ async def generate_preset_theme_from_theme_names(self, name : str, themeNames :
except Exception as e:
return Result(False, str(e))

async def upload_theme(self, name : str, base_url : str, bearer_token : str) -> Result:
theme = await self._get_theme(name)

if theme is None:
return Result(False, f"Could not find theme {name}")

try:
return await upload(theme, base_url, bearer_token)
except Exception as e:
return Result(False, str(e))

async def _enable_theme(self, theme : Theme, set_deps : bool = True, set_deps_value : bool = True, ignore_dependencies : list = []) -> Result:
if theme is None:
return Result(False)
Expand Down
32 changes: 29 additions & 3 deletions css_remoteinstall.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import asyncio, json, tempfile, os, aiohttp, zipfile
import asyncio, json, tempfile, os, aiohttp, zipfile, shutil
from css_utils import Result, Log, get_theme_path, store_or_file_config
from css_theme import CSS_LOADER_VER
from css_theme import CSS_LOADER_VER, Theme

async def run(command : str) -> str:
proc = await asyncio.create_subprocess_shell(command,
Expand Down Expand Up @@ -64,4 +64,30 @@ async def install(id : str, base_url : str, local_themes : list) -> Result:

await install(x["id"], base_url, local_themes)

return Result(True)
return Result(True)

async def upload(theme : Theme, base_url : str, bearer_token : str) -> Result:
if not base_url.endswith("/"):
base_url = base_url + "/"

url = f"{base_url}blobs"

with tempfile.TemporaryDirectory() as tmp:
themePath = os.path.join(tmp, "theme.zip")
print(themePath[:-4])
print(theme.themePath)
shutil.make_archive(themePath[:-4], 'zip', theme.themePath)

with open(themePath, "rb") as file:
async with aiohttp.ClientSession(headers={"User-Agent": f"SDH-CSSLoader/{CSS_LOADER_VER}", "Authorization": f"Bearer {bearer_token}"}, connector=aiohttp.TCPConnector(verify_ssl=False)) as session:
try:
mp = aiohttp.FormData()
mp.add_field("file", file)
async with session.post(url, data=mp) as resp:
if resp.status != 200:
raise Exception(f"Invalid status code {resp.status}")

data = await resp.json()
return Result(True, data)
except Exception as e:
return Result(False, str(e))
42 changes: 40 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import os, asyncio, sys, time
import os, asyncio, sys, time, aiohttp, json

from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer

sys.path.append(os.path.dirname(__file__))

from css_utils import Log, create_steam_symlink, Result, get_theme_path, store_read as util_store_read, store_write as util_store_write, store_or_file_config
from css_inject import ALL_INJECTS
from css_inject import ALL_INJECTS, initialize_class_mappings
from css_theme import CSS_LOADER_VER
from css_remoteinstall import install

Expand All @@ -25,6 +25,38 @@

Initialized = False

SUCCESSFUL_FETCH_THIS_RUN = False

async def fetch_class_mappings(css_translations_path : str, loader : Loader):
global SUCCESSFUL_FETCH_THIS_RUN

if SUCCESSFUL_FETCH_THIS_RUN:
return

setting = util_store_read("beta_translations")
css_translations_url = "https://api.deckthemes.com/beta.json" if (setting == "1" or setting == "true") else "https://api.deckthemes.com/stable.json"

try:
async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(verify_ssl=False), timeout=aiohttp.ClientTimeout(total=2)) as session:
async with session.get(css_translations_url) as response:
if response.status == 200:
with open(css_translations_path, "w", encoding="utf-8") as fp:
fp.write(await response.text())

SUCCESSFUL_FETCH_THIS_RUN = True
Log(f"Fetched css translations from server")
initialize_class_mappings()
asyncio.get_running_loop().create_task(loader.reset(silent=True))

except Exception as ex:
Log(f"Failed to fetch css translations from server: {str(ex)}")


async def every(__seconds: float, func, *args, **kwargs):
while True:
await func(*args, **kwargs)
await asyncio.sleep(__seconds)

class FileChangeHandler(FileSystemEventHandler):
def __init__(self, loader : Loader, loop):
self.loader = loader
Expand Down Expand Up @@ -144,6 +176,9 @@ async def get_last_load_errors(self):
return {
"fails": self.loader.last_load_errors
}

async def upload_theme(self, name : str, base_url : str, bearer_token : str) -> dict:
return (await self.loader.upload_theme(name, base_url, bearer_token)).to_dict()

async def _main(self):
global Initialized
Expand All @@ -155,6 +190,7 @@ async def _main(self):
self.server_loaded = False

Log("Initializing css loader...")
initialize_class_mappings()
Log(f"Max supported manifest version: {CSS_LOADER_VER}")

create_steam_symlink()
Expand All @@ -172,6 +208,8 @@ async def _main(self):
if (ALWAYS_RUN_SERVER or store_or_file_config("server")):
await self.enable_server(self)

css_translations_path = os.path.join(get_theme_path(), "css_translations.json")
asyncio.get_event_loop().create_task(every(60, fetch_class_mappings, css_translations_path, self.loader))
await initialize()

if __name__ == '__main__':
Expand Down
Loading

0 comments on commit 2e5920b

Please sign in to comment.