From ec1e905c17bae6137fd2f7a6ab2950c001564731 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Thu, 21 Dec 2023 12:02:26 +0800 Subject: [PATCH 01/58] Add support for description header --- .../example-theme-textemojis.clithemedef.txt | 1 + src/clitheme/_generator.py | 2 +- src/clitheme/cli.py | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/example-clithemedef/example-theme-textemojis.clithemedef.txt b/example-clithemedef/example-theme-textemojis.clithemedef.txt index 2561753..8c88183 100644 --- a/example-clithemedef/example-theme-textemojis.clithemedef.txt +++ b/example-clithemedef/example-theme-textemojis.clithemedef.txt @@ -1,5 +1,6 @@ begin_header name 颜文字样例主题 + description 适配项目中提供的example程序的一个颜文字主题,把它的输出变得可爱 version 1.0 locales zh_CN supported_apps clitheme_example diff --git a/src/clitheme/_generator.py b/src/clitheme/_generator.py index 57c31eb..72c5c58 100644 --- a/src/clitheme/_generator.py +++ b/src/clitheme/_generator.py @@ -109,7 +109,7 @@ def generate_data_hierarchy(file_content, custom_path_gen=True, custom_infofile_ current_status="main" else: handle_error("Unexpected \"{}\" on line {}".format(phrases[0],str(linenumber))) elif current_status=="header": # expect name, version, locales, or end_header - if phrases[0]=="name" or phrases[0]=="version" or phrases[0]=="locales" or phrases[0]=="supported_apps": + if phrases[0]=="name" or phrases[0]=="version" or phrases[0]=="locales" or phrases[0]=="supported_apps" or phrases[0]=="description": if len(phrases)<2: handle_error("Not enough arguments for {} line at line {}"\ .format(phrases[0],str(linenumber))) diff --git a/src/clitheme/cli.py b/src/clitheme/cli.py index 725ccd2..972080b 100755 --- a/src/clitheme/cli.py +++ b/src/clitheme/cli.py @@ -151,6 +151,12 @@ def get_current_theme_info(): if os.path.isfile(target_path+"/"+"clithemeinfo_version"): version=open(target_path+"/"+"clithemeinfo_version", 'r').read().strip() print("Version: {}".format(version)) + # description + description="(Unknown)" + if os.path.isfile(target_path+"/"+"clithemeinfo_description"): + description=open(target_path+"/"+"clithemeinfo_description", 'r').read().strip() + print("Description:") + print(description) # locales locales="(Unknown)" if os.path.isfile(target_path+"/"+"clithemeinfo_locales"): -- Gitee From 36867d6194fc04c0e440d7c750139e18e0052bd1 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Thu, 21 Dec 2023 12:06:39 +0800 Subject: [PATCH 02/58] Remove unused code in _generator --- src/clitheme/_generator.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/clitheme/_generator.py b/src/clitheme/_generator.py index 72c5c58..b89abb2 100644 --- a/src/clitheme/_generator.py +++ b/src/clitheme/_generator.py @@ -1,26 +1,19 @@ """ Generator function used in applying themes (should not be invoked directly) """ -import os,sys +import os import string import random -import warnings try: from . import _globalvar except ImportError: # for test program import _globalvar -header_begin=\ - """# clitheme theme info header - # This file is automatically generated by clitheme and should not be edited - """ - path="" # to be generated by function def handle_error(message): raise SyntaxError(message) def handle_warning(message): - # warnings.warn(message,SyntaxWarning) print("Warning: {}".format(message)) def recursive_mkdir(path, entry_name, line_number_debug): # recursively generate directories (excluding file itself) current_path=path @@ -79,8 +72,6 @@ def generate_data_hierarchy(file_content, custom_path_gen=True, custom_infofile_ if not os.path.exists(path): os.mkdir(path) datapath=path+"/"+_globalvar.generator_data_pathname if not os.path.exists(datapath): os.mkdir(datapath) - # headerinfo_file=open(path+"/current-theme.clithemeheader",'x') - # headerinfo_file.write(header_begin) current_status="" # header, main, entry linenumber=0 # To detect repeated blocks -- Gitee From 32208dea2158b6668f5a912e7636c7c66a6346a6 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Thu, 21 Dec 2023 12:17:33 +0800 Subject: [PATCH 03/58] Fix spelling errors in comments and messages --- src/clitheme/_generator.py | 2 +- src/clitheme/_globalvar.py | 6 +++--- src/clitheme/cli.py | 6 +++--- src/clitheme/frontend.py | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/clitheme/_generator.py b/src/clitheme/_generator.py index b89abb2..6778608 100644 --- a/src/clitheme/_generator.py +++ b/src/clitheme/_generator.py @@ -183,4 +183,4 @@ def generate_data_hierarchy(file_content, custom_path_gen=True, custom_infofile_ # Update current theme index theme_index=open(path+"/"+_globalvar.generator_info_pathname+"/"+_globalvar.generator_index_filename, 'w') theme_index.write(custom_infofile_name+"\n") - return True # Everything is successul! :) \ No newline at end of file + return True # Everything is successful! :) diff --git a/src/clitheme/_globalvar.py b/src/clitheme/_globalvar.py index 2c6bb7e..411981b 100644 --- a/src/clitheme/_globalvar.py +++ b/src/clitheme/_globalvar.py @@ -17,7 +17,7 @@ if clitheme_root_data_path=="": # prev did not succeed raise KeyError clitheme_root_data_path=os.environ["HOME"]+"/.local/share/clitheme" except KeyError: - print("[clitheme] Error: unable to get your home directory or invaild home directory information") + print("[clitheme] Error: unable to get your home directory or invalid home directory information") print("Please make sure that the $HOME environment variable is set correctly.") print("Try restarting your terminal session to fix this issue.") exit(1) @@ -27,7 +27,7 @@ generator_info_pathname="theme-info" # e.g. ~/.local/share/clitheme/theme-info generator_data_pathname="theme-data" # e.g. ~/.local/share/clitheme/theme-data generator_index_filename="current_theme_index" entry_banphrases=['/','\\'] -# function to check whether the pathname contains invaild phrases +# function to check whether the pathname contains invalid phrases # - cannot start with . # - cannot contain banphrases sanity_check_error_message="" @@ -41,4 +41,4 @@ def sanity_check(path): if p.find(b)!=-1: sanity_check_error_message="cannot contain '{}'".format(b) return False - return True \ No newline at end of file + return True diff --git a/src/clitheme/cli.py b/src/clitheme/cli.py index 972080b..970249b 100755 --- a/src/clitheme/cli.py +++ b/src/clitheme/cli.py @@ -210,7 +210,7 @@ def main(cli_args): try: contents=open(path, 'r').read() except Exception: - print("An error occured while reading the file: \n{}".format(str(sys.exc_info()[1]))) + print("An error occurred while reading the file: \n{}".format(str(sys.exc_info()[1]))) return 1 return apply_theme(contents, overlay=overlay, preserve_temp=preserve_temp) elif cli_args[1]=="get-current-theme-info": @@ -238,7 +238,7 @@ def main(cli_args): try: contents=open(path, 'r').read() except Exception: - print("An error occured while reading the file: \n{}".format(str(sys.exc_info()[1]))) + print("An error occurred while reading the file: \n{}".format(str(sys.exc_info()[1]))) return 1 return generate_data_hierarchy(contents, overlay=overlay) elif cli_args[1]=="--version": @@ -252,4 +252,4 @@ def main(cli_args): def script_main(): # for script exit(main(sys.argv)) if __name__=="__main__": - exit(main(sys.argv)) \ No newline at end of file + exit(main(sys.argv)) diff --git a/src/clitheme/frontend.py b/src/clitheme/frontend.py index 8c3f372..d9d2cc0 100644 --- a/src/clitheme/frontend.py +++ b/src/clitheme/frontend.py @@ -95,7 +95,7 @@ class FetchDescriptor(): path=data_path+"/"+self.domain_name+"/"+self.app_name+"/"+self.subsections for section in entry_path.split(): path+="/"+section - # path with lang, path with lang but without e.g. .UTF-8, path wth no lang + # path with lang, path with lang but without e.g. .UTF-8, path with no lang possible_paths=[path+"__"+lang, path+"__"+lang_without_encoding, path] for p in possible_paths: if self.debug_mode: print("Trying "+p, end="...") @@ -121,4 +121,4 @@ class FetchDescriptor(): fallback_string+=random.choice(string.ascii_letters) recieved_content=self.retrieve_entry_or_fallback(entry_path, fallback_string) if recieved_content.strip()==fallback_string: return False - else: return True \ No newline at end of file + else: return True -- Gitee From 905dbc5389a948c47cd86089fdde7dc10ee11177 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Thu, 21 Dec 2023 12:25:38 +0800 Subject: [PATCH 04/58] Change command display name to "clitheme" --- src/clitheme/cli.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/clitheme/cli.py b/src/clitheme/cli.py index 970249b..59bbc19 100755 --- a/src/clitheme/cli.py +++ b/src/clitheme/cli.py @@ -186,14 +186,15 @@ def main(cli_args): Provide a list of command line arguments to this function through cli_args. """ + arg_first="clitheme" # controls what appears as the command name in messages if len(cli_args)<=1: # no arguments passed - print(usage_description.format(cli_args[0])) + print(usage_description.format(arg_first)) print("Error: no command or option specified") return 1 if cli_args[1]=="apply-theme": if len(cli_args)<3: - return handle_usage_error("Error: not enough arguments", cli_args[0]) + return handle_usage_error("Error: not enough arguments", arg_first) path="" overlay=False preserve_temp=False @@ -201,10 +202,10 @@ def main(cli_args): if is_option(arg): if arg.strip()=="--overlay": overlay=True elif arg.strip()=="--preserve-temp": preserve_temp=True - else: return handle_usage_error("Unknown option \"{}\"".format(arg), cli_args[0]) + else: return handle_usage_error("Unknown option \"{}\"".format(arg), arg_first) else: if path!="": # already specified path - return handle_usage_error("Error: too many arguments", cli_args[0]) + return handle_usage_error("Error: too many arguments", arg_first) path=arg contents="" try: @@ -215,24 +216,24 @@ def main(cli_args): return apply_theme(contents, overlay=overlay, preserve_temp=preserve_temp) elif cli_args[1]=="get-current-theme-info": if len(cli_args)>2: # disabled additional options - return handle_usage_error("Error: too many arguments", cli_args[0]) + return handle_usage_error("Error: too many arguments", arg_first) return get_current_theme_info() elif cli_args[1]=="unset-current-theme": if len(cli_args)>2: - return handle_usage_error("Error: too many arguments", cli_args[0]) + return handle_usage_error("Error: too many arguments", arg_first) return unset_current_theme() elif cli_args[1]=="generate-data-hierarchy": if len(cli_args)<3: - return handle_usage_error("Error: not enough arguments", cli_args[0]) + return handle_usage_error("Error: not enough arguments", arg_first) path="" overlay=False for arg in cli_args[2:]: if is_option(arg): if arg.strip()=="--overlay": overlay=True - else: return handle_usage_error("Unknown option \"{}\"".format(arg), cli_args[0]) + else: return handle_usage_error("Unknown option \"{}\"".format(arg), arg_first) else: if path!="": # already specified path - return handle_usage_error("Error: too many arguments", cli_args[0]) + return handle_usage_error("Error: too many arguments", arg_first) path=arg contents="" try: @@ -245,9 +246,9 @@ def main(cli_args): print("clitheme version {0}".format(_globalvar.clitheme_version)) else: if cli_args[1]=="--help": - print(usage_description.format(cli_args[0])) + print(usage_description.format(arg_first)) else: - return handle_usage_error("Error: unknown command \"{0}\"".format(cli_args[1]), cli_args[0]) + return handle_usage_error("Error: unknown command \"{0}\"".format(cli_args[1]), arg_first) return 0 def script_main(): # for script exit(main(sys.argv)) -- Gitee From 022215290b65cd65e9f63eb79711385d5c6cd68a Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Thu, 21 Dec 2023 19:50:02 +0800 Subject: [PATCH 05/58] Update version (20231221) --- debian/changelog | 6 ++++++ src/clitheme/_version.py | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index 46a1dc3..f97eec7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +clitheme (1.1-dev20231221-1) experimental; urgency=low + + * In development + + -- swiftycode <3291929745@qq.com> Thu, 21 Dec 2023 19:48:00 +0800 + clitheme (1.0-r2-1) unstable; urgency=medium * Version 1.0-r2 in Debian package format diff --git a/src/clitheme/_version.py b/src/clitheme/_version.py index a9896ab..24cb6c5 100644 --- a/src/clitheme/_version.py +++ b/src/clitheme/_version.py @@ -1,10 +1,10 @@ # Version definition file; define the package version here # Version CANNOT contain hyphens (-); use underscores (_) instead # The __version__ variable must be a literal string; DO NOT use variables -__version__="1.0-r2" +__version__="1.1-dev20231221" major=1 -minor=0 -release=2 # 0 stands for "dev" +minor=1 +release=0 # 0 stands for "dev" # For PKGBUILD -version_main="1.0_r2" +version_main="1.1_dev20231221" version_buildnumber=1 \ No newline at end of file -- Gitee From 347a026898832429ce217f5534b39a511b720727 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sat, 23 Dec 2023 00:17:30 +0800 Subject: [PATCH 06/58] Add block handling support for entries, including whitespace processing --- clitheme-testblock_testprogram.py | 40 ++++++++++++++++++++ src/clitheme/_generator.py | 63 ++++++++++++++++++++++++++++++- 2 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 clitheme-testblock_testprogram.py diff --git a/clitheme-testblock_testprogram.py b/clitheme-testblock_testprogram.py new file mode 100644 index 0000000..754e791 --- /dev/null +++ b/clitheme-testblock_testprogram.py @@ -0,0 +1,40 @@ +#!/usr/bin/python3 + +# Program for testing multi-line (block) processing of _generator +from src.clitheme import _generator, frontend, _globalvar + +file_data=""" +begin_header + name untitled +end_header + +begin_main + entry test_entry + locale_block default + this + and + that + + is just good + #enough + end_block + locale_block zh_CN + 这是一个 + 很好的东西 + + #非常好 + end_block + end_entry +end_main +""" + +_generator.generate_data_hierarchy(file_data) +frontend.data_path=_generator.path+"/"+_globalvar.generator_data_pathname +f=frontend.FetchDescriptor() +print("Default locale:") +f.disable_lang=True +print(f.reof("test_entry", "Nonexistent")) +print("zh_CN locale:") +f.disable_lang=False +f.lang="zh_CN" +print(f.reof("test_entry", "Nonexistent")) diff --git a/src/clitheme/_generator.py b/src/clitheme/_generator.py index 6778608..9ebfe8c 100644 --- a/src/clitheme/_generator.py +++ b/src/clitheme/_generator.py @@ -4,6 +4,7 @@ Generator function used in applying themes (should not be invoked directly) import os import string import random +import re try: from . import _globalvar except ImportError: # for test program @@ -77,15 +78,66 @@ def generate_data_hierarchy(file_content, custom_path_gen=True, custom_infofile_ # To detect repeated blocks headerparsed=False mainparsed=False + current_domainapp="" # for in_domainapp and unset_domainapp in main block current_entry_name="" # for entry current_subsection="" # for in_subsection + + current_entry_locale="" # for handling locale_block + current_entry_linenumber=-1 + + blockinput=False # for multi-line (block) input + blockinput_data="" # data of current block input + blockinput_minspaces=-1 # min number of whitespaces for line in file_content.splitlines(): linenumber+=1 phrases=line.split() - if line.strip()=="" or line.strip()[0]=="#": # if empty line or comment + if blockinput==False and (line.strip()=="" or line.strip()[0]=="#"): # if empty line or comment (except in block input mode) continue - if current_status=="": # expect begin_header or begin_main + + if blockinput==True: + if len(phrases)>0 and phrases[0]=="end_block": + if blockinput_minspaces!=-1: + # process whitespaces + # trim amount of leading whitespaces on each line + pattern=r"(?P\n|^)[ ]{"+str(blockinput_minspaces)+"}" + blockinput_data=re.sub(pattern,r"\g", blockinput_data) + if current_status=="entry": + target_entry=current_entry_name + if current_entry_locale!="default": + target_entry+="__"+current_entry_locale + add_entry(datapath,target_entry, blockinput_data, current_entry_linenumber) + # clear data + current_entry_locale="" + current_entry_linenumber=-1 + else: # the unlikely case + handle_error("Line {}: internal error while handling block input; please file a bug report".format(str(linenumber))) + # clear data + blockinput=False + blockinput_data="" + else: + if blockinput_data!="": blockinput_data+="\n" + line_content=line.strip() + if line_content=="": continue # empty line + # Calculate whitespaces + spaces=-1 + ws_match=re.search(r"^\s+", line) # match leading whitespaces + if ws_match==None: # no leading spaces + spaces=0 + else: + leading_whitespace=ws_match.group() + # substitute \t with 8 spaces + leading_whitespace=re.sub(r"\t"," "*8, leading_whitespace) + # append it to line_content + line_content=leading_whitespace+line_content + # write line_content to data + blockinput_data+=line_content + spaces=len(leading_whitespace) + # update min count + if spaces!=-1 and (spaces Date: Sat, 23 Dec 2023 00:21:43 +0800 Subject: [PATCH 07/58] Update version (20231222) --- debian/changelog | 6 +++--- src/clitheme/_version.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/debian/changelog b/debian/changelog index f97eec7..5d4a55b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ -clitheme (1.1-dev20231221-1) experimental; urgency=low +clitheme (1.1-dev20231222-1) experimental; urgency=low - * In development + * In development, please see commit logs for changes - -- swiftycode <3291929745@qq.com> Thu, 21 Dec 2023 19:48:00 +0800 + -- swiftycode <3291929745@qq.com> Sat, 23 Dec 2023 00:18:56 +0800 clitheme (1.0-r2-1) unstable; urgency=medium diff --git a/src/clitheme/_version.py b/src/clitheme/_version.py index 24cb6c5..f13103c 100644 --- a/src/clitheme/_version.py +++ b/src/clitheme/_version.py @@ -1,10 +1,10 @@ # Version definition file; define the package version here -# Version CANNOT contain hyphens (-); use underscores (_) instead # The __version__ variable must be a literal string; DO NOT use variables -__version__="1.1-dev20231221" +__version__="1.1-dev20231222" major=1 minor=1 release=0 # 0 stands for "dev" # For PKGBUILD -version_main="1.1_dev20231221" +# version_main CANNOT contain hyphens (-); use underscores (_) instead +version_main="1.1_dev20231222" version_buildnumber=1 \ No newline at end of file -- Gitee From 93c29461954067c8f3398d7dc7a6af02f5796e4f Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sat, 23 Dec 2023 00:25:54 +0800 Subject: [PATCH 08/58] Fix small typo in debian package description --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 9e293d4..8227c38 100644 --- a/debian/control +++ b/debian/control @@ -14,7 +14,7 @@ Multi-Arch: foreign Depends: ${misc:Depends}, python3 (> 3.7) Description: Application framework for text theming clitheme allows users to customize the output of supported programs, such as - multi-language support or mimicing your favorite cartoon character. It has an + multi-language support or mimicking your favorite cartoon character. It has an easy-to-understand syntax and implementation module for programs. . For more information, visit the homepage and the pages in the Wiki section. -- Gitee From 73b9e94c704a307f1b16d3d5638d882ca26a1d08 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sat, 23 Dec 2023 11:22:26 +0800 Subject: [PATCH 09/58] Improve leading/trailing newlines handlig --- clitheme-testblock_testprogram.py | 18 +++++++++++++++++- src/clitheme/_generator.py | 6 ++++-- src/clitheme/frontend.py | 6 ++++-- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/clitheme-testblock_testprogram.py b/clitheme-testblock_testprogram.py index 754e791..a8258cf 100644 --- a/clitheme-testblock_testprogram.py +++ b/clitheme-testblock_testprogram.py @@ -11,18 +11,31 @@ end_header begin_main entry test_entry locale_block default + + this and that is just good - #enough + #enough + should have leading 2 lines and trailing 3 lines + + + end_block locale_block zh_CN + + + 这是一个 很好的东西 #非常好 + ... + should have leading 3 lines and trailing 2 lines + + end_block end_entry end_main @@ -38,3 +51,6 @@ print("zh_CN locale:") f.disable_lang=False f.lang="zh_CN" print(f.reof("test_entry", "Nonexistent")) + +import shutil +shutil.rmtree(_generator.path) \ No newline at end of file diff --git a/src/clitheme/_generator.py b/src/clitheme/_generator.py index 9ebfe8c..e8f9fed 100644 --- a/src/clitheme/_generator.py +++ b/src/clitheme/_generator.py @@ -118,7 +118,9 @@ def generate_data_hierarchy(file_content, custom_path_gen=True, custom_infofile_ else: if blockinput_data!="": blockinput_data+="\n" line_content=line.strip() - if line_content=="": continue # empty line + if line_content=="": # empty line + if blockinput_data=="": blockinput_data+=" " + continue # Calculate whitespaces spaces=-1 ws_match=re.search(r"^\s+", line) # match leading whitespaces @@ -225,7 +227,7 @@ def generate_data_hierarchy(file_content, custom_path_gen=True, custom_infofile_ if phrases[1]!="default": target_entry+="__"+phrases[1] add_entry(datapath,target_entry,content,linenumber) - if phrases[0]=="locale_block": + elif phrases[0]=="locale_block": if len(phrases)!=2: handle_error("Format error in {} at line {}".format(phrases[0],linenumber)) current_entry_locale=phrases[1] diff --git a/src/clitheme/frontend.py b/src/clitheme/frontend.py index d9d2cc0..6c70fc3 100644 --- a/src/clitheme/frontend.py +++ b/src/clitheme/frontend.py @@ -5,6 +5,7 @@ clitheme front-end interface for accessing entries import os,sys import random import string +import re from typing import Optional try: from . import _globalvar @@ -101,9 +102,10 @@ class FetchDescriptor(): if self.debug_mode: print("Trying "+p, end="...") try: f=open(p,'r') - dat=f.read().strip() + dat=f.read() if self.debug_mode: print("Success:\n> "+dat) - return dat + # since the generator adds an extra newline in the entry data, we need to remove it + return re.sub(r"\n\Z", "", dat) except (FileNotFoundError, IsADirectoryError): if self.debug_mode: print("Failed") return fallback_string -- Gitee From f40ff27882941860208fbf769cdc41414d90cea2 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sat, 23 Dec 2023 13:32:16 +0800 Subject: [PATCH 10/58] Support multi-line input for description, supported_apps, and locales header --- .../example-theme-textemojis.clithemedef.txt | 23 +++++++-- src/clitheme/_generator.py | 48 ++++++++++++++++++- src/clitheme/cli.py | 19 ++++++-- 3 files changed, 81 insertions(+), 9 deletions(-) diff --git a/example-clithemedef/example-theme-textemojis.clithemedef.txt b/example-clithemedef/example-theme-textemojis.clithemedef.txt index 8c88183..afd87ce 100644 --- a/example-clithemedef/example-theme-textemojis.clithemedef.txt +++ b/example-clithemedef/example-theme-textemojis.clithemedef.txt @@ -1,9 +1,24 @@ begin_header name 颜文字样例主题 - description 适配项目中提供的example程序的一个颜文字主题,把它的输出变得可爱 version 1.0 - locales zh_CN - supported_apps clitheme_example + # testing block input + locales_block + Simplified Chinese + 简体中文 + zh_CN + end_block + supported_apps_block + clitheme example + clitheme 样例应用 + clitheme_example + end_block + description_block + 适配项目中提供的example程序的一个颜文字主题,把它的输出变得可爱。 + 应用这个主题,沉浸在颜文字的世界中吧! + + 不要小看我的年龄,人家可是非常萌的~! + end_block + end_header begin_main @@ -50,4 +65,4 @@ begin_main locale default ಥ_ಥ 找不到指令"{}"!呜呜呜~ locale zh_CN ಥ_ಥ 找不到指令"{}"!呜呜呜~ end_entry -end_main \ No newline at end of file +end_main diff --git a/src/clitheme/_generator.py b/src/clitheme/_generator.py index e8f9fed..ba30af4 100644 --- a/src/clitheme/_generator.py +++ b/src/clitheme/_generator.py @@ -54,6 +54,17 @@ def write_infofile(path,filename,content,line_number_debug, header_name_debug): f=open(target_path,'w') f.write(content+'\n') +def write_infofile_v2(path: str, filename: str, content_phrases: list[str], line_number_debug: int, header_name_debug: str): + if not os.path.isdir(path): + os.makedirs(path) + target_path=path+"/"+filename + if os.path.isfile(target_path): + handle_warning("Line {}: repeated header info \"{}\", overwriting"\ + .format(str(line_number_debug), header_name_debug)) + f=open(target_path,'w') + for line in content_phrases: + f.write(line+"\n") + def generate_custom_path(): # Generate a temporary path global path @@ -86,6 +97,9 @@ def generate_data_hierarchy(file_content, custom_path_gen=True, custom_infofile_ current_entry_locale="" # for handling locale_block current_entry_linenumber=-1 + current_header_entry="" # for block input in header + current_header_linenumber=-1 + blockinput=False # for multi-line (block) input blockinput_data="" # data of current block input blockinput_minspaces=-1 # min number of whitespaces @@ -110,6 +124,24 @@ def generate_data_hierarchy(file_content, custom_path_gen=True, custom_infofile_ # clear data current_entry_locale="" current_entry_linenumber=-1 + elif current_status=="header": + if current_header_entry!="description": + # trim all leading whitespaces + blockinput_data=re.sub(r"(?P\n|^)[ ]+",r"\g", blockinput_data) + # trim all trailing whitespaces + blockinput_data=re.sub(r"[ ]+(?P\n|$)",r"\g", blockinput_data) + # trim all leading/trailing newlines + blockinput_data=re.sub(r"(\A\n+|\n+\Z)", "", blockinput_data) + filename="clithemeinfo_"+current_header_entry+"_v2" + if current_header_entry=="description": + filename="clithemeinfo_"+current_header_entry + write_infofile( \ + path+"/"+_globalvar.generator_info_pathname+"/"+custom_infofile_name, \ + filename,\ + blockinput_data,current_header_linenumber,current_header_entry) # e.g. [...]/theme-info/1/clithemeinfo_description_v2 + # clear data + current_header_entry="" + current_header_linenumber=-1 else: # the unlikely case handle_error("Line {}: internal error while handling block input; please file a bug report".format(str(linenumber))) # clear data @@ -154,16 +186,28 @@ def generate_data_hierarchy(file_content, custom_path_gen=True, custom_infofile_ current_status="main" else: handle_error("Unexpected \"{}\" on line {}".format(phrases[0],str(linenumber))) elif current_status=="header": # expect name, version, locales, or end_header - if phrases[0]=="name" or phrases[0]=="version" or phrases[0]=="locales" or phrases[0]=="supported_apps" or phrases[0]=="description": + if phrases[0]=="name" or phrases[0]=="version" or phrases[0]=="description": if len(phrases)<2: handle_error("Not enough arguments for {} line at line {}"\ .format(phrases[0],str(linenumber))) - # headerinfo_file.write(line.strip()+"\n") content=splitarray_to_string(phrases[1:]) write_infofile( \ path+"/"+_globalvar.generator_info_pathname+"/"+custom_infofile_name, \ "clithemeinfo_"+phrases[0],\ content,linenumber,phrases[0]) # e.g. [...]/theme-info/1/clithemeinfo_name + elif phrases[0]=="locales" or phrases[0]=="supported_apps": + if len(phrases)<2: + handle_error("Not enough arguments for {} line at line {}"\ + .format(phrases[0],str(linenumber))) + content=phrases[1:] + write_infofile_v2( \ + path+"/"+_globalvar.generator_info_pathname+"/"+custom_infofile_name, \ + "clithemeinfo_"+phrases[0]+"_v2",\ + content,linenumber,phrases[0]) # e.g. [...]/theme-info/1/clithemeinfo_description_v2 + elif phrases[0]=="locales_block" or phrases[0]=="supported_apps_block" or phrases[0]=="description_block": + current_header_entry=re.sub(r"_block$", "", phrases[0]) + current_header_linenumber=linenumber + blockinput=True # start block input mode elif phrases[0]=="end_header": if len(phrases)!=1: handle_error("Extra arguments after \"{}\" on line {}".format(phrases[0],str(linenumber))) diff --git a/src/clitheme/cli.py b/src/clitheme/cli.py index 59bbc19..4dc2d05 100755 --- a/src/clitheme/cli.py +++ b/src/clitheme/cli.py @@ -154,19 +154,32 @@ def get_current_theme_info(): # description description="(Unknown)" if os.path.isfile(target_path+"/"+"clithemeinfo_description"): - description=open(target_path+"/"+"clithemeinfo_description", 'r').read().strip() + description=open(target_path+"/"+"clithemeinfo_description", 'r').read() print("Description:") print(description) # locales locales="(Unknown)" - if os.path.isfile(target_path+"/"+"clithemeinfo_locales"): + # version 2: items are seperated by newlines instead of spaces + if os.path.isfile(target_path+"/"+"clithemeinfo_locales_v2"): + locales=open(target_path+"/"+"clithemeinfo_locales_v2", 'r').read().strip() + print("Supported locales:") + for locale in locales.splitlines(): + if locale.strip()!="": + print("• {}".format(locale.strip())) + elif os.path.isfile(target_path+"/"+"clithemeinfo_locales"): locales=open(target_path+"/"+"clithemeinfo_locales", 'r').read().strip() print("Supported locales: ") for locale in locales.split(): print("• {}".format(locale)) # supported_apps supported_apps="(Unknown)" - if os.path.isfile(target_path+"/"+"clithemeinfo_supported_apps"): + if os.path.isfile(target_path+"/"+"clithemeinfo_supported_apps_v2"): + supported_apps=open(target_path+"/"+"clithemeinfo_supported_apps_v2", 'r').read().strip() + print("Supported apps: ") + for app in supported_apps.splitlines(): + if app.strip()!="": + print("• {}".format(app)) + elif os.path.isfile(target_path+"/"+"clithemeinfo_supported_apps"): supported_apps=open(target_path+"/"+"clithemeinfo_supported_apps", 'r').read().strip() print("Supported apps: ") for app in supported_apps.split(): -- Gitee From 5386ff3f9aa6c0ad8077d629a5fc97037488da0f Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sat, 23 Dec 2023 14:49:05 +0800 Subject: [PATCH 11/58] Small changes to README --- README.zh-CN.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.zh-CN.md b/README.zh-CN.md index 5374477..4ab0a93 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -37,11 +37,9 @@ $ example-app install-file foo-nonexist - 无需前端API也可访问当前主题数据(易懂的数据结构) `clitheme` 不仅可以定制命令行应用的输出,它还可以: -- 为应用添加多语言支持 +- 为应用程序添加多语言支持 - 支持图形化应用 -**注意:**`clitheme`当前仅支持拥有Python 3的Linux和macOS系统,暂不支持Windows系统。 - # 基本用法 ## 数据结构和路径名称 @@ -221,6 +219,9 @@ end_main 构建软件包只需要在仓库目录中执行`makepkg`指令就可以了。你可以通过以下一系列命令来完成这些操作: ```sh +# 如果之前执行过makepkg,请删除之前生成的临时文件夹,否则构建时会出现问题 +rm -rf buildtmp srctmp + makepkg -si # -s:自动安装构建时需要的软件包 # -i:构建完后自动安装生成的软件包 @@ -240,10 +241,11 @@ rm -rf buildtmp srctmp - `debhelper` - `dh-python` - `python3-hatchling` +- `dpkg-dev` 你可以使用以下命令安装: - sudo apt install debhelper dh-python python3-hatchling + sudo apt install debhelper dh-python python3-hatchling dpkg-dev 安装完后,请在仓库目录中执行`dpkg-buildpackage -b`以构建软件包。完成后,你会在上层目录中获得一个`.deb`的文件。 -- Gitee From ec628578941a28ec7ca41bd06bec01fe334a795c Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sat, 23 Dec 2023 15:05:28 +0800 Subject: [PATCH 12/58] Change some output of cli interface --- src/clitheme/cli.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/clitheme/cli.py b/src/clitheme/cli.py index 4dc2d05..26edd26 100755 --- a/src/clitheme/cli.py +++ b/src/clitheme/cli.py @@ -53,21 +53,21 @@ def apply_theme(file_content: str, overlay: bool, preserve_temp=False): try: _generator.generate_data_hierarchy(file_content, custom_path_gen=generate_path,custom_infofile_name=str(index)) except SyntaxError: - print("Error\nAn error occurred while generating the data:\n{}".format(str(sys.exc_info()[1]))) + print("An error occurred while generating the data:\n{}".format(str(sys.exc_info()[1]))) return 1 print("Successfully generated data") if preserve_temp: print("View at {}".format(_generator.path)) - print("==> Applying theme...",end='') + print("==> Applying theme...") # remove the current data, ignoring directory not found error try: shutil.rmtree(_globalvar.clitheme_root_data_path) except FileNotFoundError: None try: shutil.copytree(_generator.path, _globalvar.clitheme_root_data_path) except Exception: - print("Error\nAn error occurred while applying the theme:\n{}".format(str(sys.exc_info()[1]))) + print("An error occurred while applying the theme:\n{}".format(str(sys.exc_info()[1]))) return 1 - print("Success\nTheme applied successfully") + print("Theme applied successfully") if not preserve_temp: try: shutil.rmtree(_generator.path) except Exception: None @@ -111,15 +111,14 @@ def unset_current_theme(): """ Delete the current theme data hierarchy from the data path """ - print("==> Removing data...", end='') try: shutil.rmtree(_globalvar.clitheme_root_data_path) except FileNotFoundError: - print("Error\nNo theme data present (no theme was set)") + print("No theme data present (no theme was set)") return 1 except Exception: - print("Error\nAn error occurred while removing the data:\n{}".format(str(sys.exc_info()[1]))) + print("An error occurred while removing the data:\n{}".format(str(sys.exc_info()[1]))) return 1 - print("Success\nSuccessfully removed the current theme data") + print("Successfully removed the current theme data") return 0 def get_current_theme_info(): -- Gitee From b8a6e6b9c13a5260887d655407e95082ca9d3532 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sat, 23 Dec 2023 15:15:29 +0800 Subject: [PATCH 13/58] Update version (20231223) --- debian/changelog | 4 ++-- src/clitheme/_version.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index 5d4a55b..6a00a9e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ -clitheme (1.1-dev20231222-1) experimental; urgency=low +clitheme (1.1-dev20231223-1) experimental; urgency=low * In development, please see commit logs for changes - -- swiftycode <3291929745@qq.com> Sat, 23 Dec 2023 00:18:56 +0800 + -- swiftycode <3291929745@qq.com> Sat, 23 Dec 2023 13:52:14 +0800 clitheme (1.0-r2-1) unstable; urgency=medium diff --git a/src/clitheme/_version.py b/src/clitheme/_version.py index f13103c..e1bc8e8 100644 --- a/src/clitheme/_version.py +++ b/src/clitheme/_version.py @@ -1,10 +1,10 @@ # Version definition file; define the package version here # The __version__ variable must be a literal string; DO NOT use variables -__version__="1.1-dev20231222" +__version__="1.1-dev20231223" major=1 minor=1 release=0 # 0 stands for "dev" # For PKGBUILD # version_main CANNOT contain hyphens (-); use underscores (_) instead -version_main="1.1_dev20231222" +version_main="1.1_dev20231223" version_buildnumber=1 \ No newline at end of file -- Gitee From 6300fcd70713454d2951453eebfa0c3a3ef70f22 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sat, 23 Dec 2023 17:48:47 +0800 Subject: [PATCH 14/58] Add Windows compatibility --- src/clitheme/_generator.py | 8 ++++---- src/clitheme/_globalvar.py | 22 ++++++++++++++++------ src/clitheme/cli.py | 33 ++++++++++++++++++++------------- src/clitheme/frontend.py | 2 +- 4 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/clitheme/_generator.py b/src/clitheme/_generator.py index ba30af4..67060b9 100644 --- a/src/clitheme/_generator.py +++ b/src/clitheme/_generator.py @@ -37,7 +37,7 @@ def add_entry(path, entry_name, entry_content, line_number_debug): # add entry t elif os.path.isfile(target_path): handle_warning("Line {}: repeated entry \"{}\", overwriting"\ .format(str(line_number_debug),entry_name)) - f=open(target_path,'w') + f=open(target_path,'w', encoding="utf-8") f.write(entry_content+"\n") def splitarray_to_string(split_content): final="" @@ -51,7 +51,7 @@ def write_infofile(path,filename,content,line_number_debug, header_name_debug): if os.path.isfile(target_path): handle_warning("Line {}: repeated header info \"{}\", overwriting"\ .format(str(line_number_debug), header_name_debug)) - f=open(target_path,'w') + f=open(target_path,'w', encoding="utf-8") f.write(content+'\n') def write_infofile_v2(path: str, filename: str, content_phrases: list[str], line_number_debug: int, header_name_debug: str): @@ -61,7 +61,7 @@ def write_infofile_v2(path: str, filename: str, content_phrases: list[str], line if os.path.isfile(target_path): handle_warning("Line {}: repeated header info \"{}\", overwriting"\ .format(str(line_number_debug), header_name_debug)) - f=open(target_path,'w') + f=open(target_path,'w', encoding="utf-8") for line in content_phrases: f.write(line+"\n") @@ -286,6 +286,6 @@ def generate_data_hierarchy(file_content, custom_path_gen=True, custom_infofile_ if not headerparsed or not mainparsed: handle_error("Missing or incomplete header or main block") # Update current theme index - theme_index=open(path+"/"+_globalvar.generator_info_pathname+"/"+_globalvar.generator_index_filename, 'w') + theme_index=open(path+"/"+_globalvar.generator_info_pathname+"/"+_globalvar.generator_index_filename, 'w', encoding="utf-8") theme_index.write(custom_infofile_name+"\n") return True # Everything is successful! :) diff --git a/src/clitheme/_globalvar.py b/src/clitheme/_globalvar.py index 411981b..39e2c07 100644 --- a/src/clitheme/_globalvar.py +++ b/src/clitheme/_globalvar.py @@ -7,21 +7,31 @@ try: from . import _version except ImportError: import _version clitheme_root_data_path="" -try: - clitheme_root_data_path=os.environ["XDG_DATA_HOME"]+"/clitheme" -except KeyError: None +if os.name=="nt": # Windows + try: + clitheme_root_data_path=os.environ["LOCALAPPDATA"]+"\\clitheme" + except KeyError: None +else: + try: + clitheme_root_data_path=os.environ["XDG_DATA_HOME"]+"/clitheme" + except KeyError: None if clitheme_root_data_path=="": # prev did not succeed try: - if not os.environ['HOME'].startswith("/"): # sanity check - raise KeyError - clitheme_root_data_path=os.environ["HOME"]+"/.local/share/clitheme" + if os.name=="nt": + clitheme_root_data_path=os.environ["USERPROFILE"]+"\\AppData\\Local\\clitheme" + else: + if not os.environ['HOME'].startswith('/'): # sanity check + raise KeyError + clitheme_root_data_path=os.environ["HOME"]+"/.local/share/clitheme" except KeyError: print("[clitheme] Error: unable to get your home directory or invalid home directory information") print("Please make sure that the $HOME environment variable is set correctly.") print("Try restarting your terminal session to fix this issue.") exit(1) clitheme_temp_root="/tmp" +if os.name=="nt": + clitheme_temp_root=os.environ['TEMP'] clitheme_version=_version.__version__ generator_info_pathname="theme-info" # e.g. ~/.local/share/clitheme/theme-info generator_data_pathname="theme-data" # e.g. ~/.local/share/clitheme/theme-data diff --git a/src/clitheme/cli.py b/src/clitheme/cli.py index 26edd26..6f74f1b 100755 --- a/src/clitheme/cli.py +++ b/src/clitheme/cli.py @@ -7,6 +7,7 @@ clitheme command line utility interface import os import sys import shutil +import re try: from . import _globalvar from . import _generator @@ -40,7 +41,7 @@ def apply_theme(file_content: str, overlay: bool, preserve_temp=False): print("Try setting a theme first") return 1 # update index - try: index=int(open(_globalvar.clitheme_root_data_path+"/"+_globalvar.generator_info_pathname+"/"+_globalvar.generator_index_filename,'r').read().strip())+1 + try: index=int(open(_globalvar.clitheme_root_data_path+"/"+_globalvar.generator_info_pathname+"/"+_globalvar.generator_index_filename,'r', encoding="utf-8").read().strip())+1 except ValueError: print("Error: the current data is corrupt") print("Remove the current theme, set the theme, and try again") @@ -57,7 +58,10 @@ def apply_theme(file_content: str, overlay: bool, preserve_temp=False): return 1 print("Successfully generated data") if preserve_temp: - print("View at {}".format(_generator.path)) + if os.name=="nt": + print("View at {}".format(re.sub(r"/", r"\\", _generator.path))) # make the output look pretty + else: + print("View at {}".format(_generator.path)) print("==> Applying theme...") # remove the current data, ignoring directory not found error try: shutil.rmtree(_globalvar.clitheme_root_data_path) @@ -88,7 +92,7 @@ def generate_data_hierarchy(file_content: str, overlay: bool): print("Try setting a theme first") return 1 # update index - try: index=int(open(_globalvar.clitheme_root_data_path+"/"+_globalvar.generator_info_pathname+"/"+_globalvar.generator_index_filename,'r').read().strip())+1 + try: index=int(open(_globalvar.clitheme_root_data_path+"/"+_globalvar.generator_info_pathname+"/"+_globalvar.generator_index_filename,'r', encoding="utf-8").read().strip())+1 except ValueError: print("Error: the current data is corrupt") print("Remove the current theme, set the theme, and try again") @@ -104,7 +108,10 @@ def generate_data_hierarchy(file_content: str, overlay: bool): print("Error\nAn error occurred while generating the data:\n{}".format(str(sys.exc_info()[1]))) return 1 print("Successfully generated data") - print("View at {}".format(_generator.path)) + if os.name=="nt": + print("View at {}".format(re.sub(r"/", r"\\", _generator.path))) # make the output look pretty + else: + print("View at {}".format(_generator.path)) return 0 def unset_current_theme(): @@ -143,43 +150,43 @@ def get_current_theme_info(): # name name="(Unknown)" if os.path.isfile(target_path+"/"+"clithemeinfo_name"): - name=open(target_path+"/"+"clithemeinfo_name", 'r').read().strip() + name=open(target_path+"/"+"clithemeinfo_name", 'r', encoding="utf-8").read().strip() print("[{}]: {}".format(theme_pathname, name)) # version version="(Unknown)" if os.path.isfile(target_path+"/"+"clithemeinfo_version"): - version=open(target_path+"/"+"clithemeinfo_version", 'r').read().strip() + version=open(target_path+"/"+"clithemeinfo_version", 'r', encoding="utf-8").read().strip() print("Version: {}".format(version)) # description description="(Unknown)" if os.path.isfile(target_path+"/"+"clithemeinfo_description"): - description=open(target_path+"/"+"clithemeinfo_description", 'r').read() + description=open(target_path+"/"+"clithemeinfo_description", 'r', encoding="utf-8").read() print("Description:") print(description) # locales locales="(Unknown)" # version 2: items are seperated by newlines instead of spaces if os.path.isfile(target_path+"/"+"clithemeinfo_locales_v2"): - locales=open(target_path+"/"+"clithemeinfo_locales_v2", 'r').read().strip() + locales=open(target_path+"/"+"clithemeinfo_locales_v2", 'r', encoding="utf-8").read().strip() print("Supported locales:") for locale in locales.splitlines(): if locale.strip()!="": print("• {}".format(locale.strip())) elif os.path.isfile(target_path+"/"+"clithemeinfo_locales"): - locales=open(target_path+"/"+"clithemeinfo_locales", 'r').read().strip() + locales=open(target_path+"/"+"clithemeinfo_locales", 'r', encoding="utf-8").read().strip() print("Supported locales: ") for locale in locales.split(): print("• {}".format(locale)) # supported_apps supported_apps="(Unknown)" if os.path.isfile(target_path+"/"+"clithemeinfo_supported_apps_v2"): - supported_apps=open(target_path+"/"+"clithemeinfo_supported_apps_v2", 'r').read().strip() + supported_apps=open(target_path+"/"+"clithemeinfo_supported_apps_v2", 'r', encoding="utf-8").read().strip() print("Supported apps: ") for app in supported_apps.splitlines(): if app.strip()!="": print("• {}".format(app)) elif os.path.isfile(target_path+"/"+"clithemeinfo_supported_apps"): - supported_apps=open(target_path+"/"+"clithemeinfo_supported_apps", 'r').read().strip() + supported_apps=open(target_path+"/"+"clithemeinfo_supported_apps", 'r', encoding="utf-8").read().strip() print("Supported apps: ") for app in supported_apps.split(): print("• {}".format(app)) @@ -221,7 +228,7 @@ def main(cli_args): path=arg contents="" try: - contents=open(path, 'r').read() + contents=open(path, 'r', encoding="utf-8").read() except Exception: print("An error occurred while reading the file: \n{}".format(str(sys.exc_info()[1]))) return 1 @@ -249,7 +256,7 @@ def main(cli_args): path=arg contents="" try: - contents=open(path, 'r').read() + contents=open(path, 'r', encoding="utf-8").read() except Exception: print("An error occurred while reading the file: \n{}".format(str(sys.exc_info()[1]))) return 1 diff --git a/src/clitheme/frontend.py b/src/clitheme/frontend.py index 6c70fc3..ac9dd4a 100644 --- a/src/clitheme/frontend.py +++ b/src/clitheme/frontend.py @@ -101,7 +101,7 @@ class FetchDescriptor(): for p in possible_paths: if self.debug_mode: print("Trying "+p, end="...") try: - f=open(p,'r') + f=open(p,'r', encoding="utf-8") dat=f.read() if self.debug_mode: print("Success:\n> "+dat) # since the generator adds an extra newline in the entry data, we need to remove it -- Gitee From 8c8e9dc146756adbe32decd9469ba40e7b5b3ef8 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sat, 23 Dec 2023 18:02:24 +0800 Subject: [PATCH 15/58] Update version (20231223) date (The real one) --- debian/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 6a00a9e..86dd753 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,7 +2,7 @@ clitheme (1.1-dev20231223-1) experimental; urgency=low * In development, please see commit logs for changes - -- swiftycode <3291929745@qq.com> Sat, 23 Dec 2023 13:52:14 +0800 + -- swiftycode <3291929745@qq.com> Sat, 23 Dec 2023 18:01:24 +0800 clitheme (1.0-r2-1) unstable; urgency=medium -- Gitee From e3ee1bbf42735b638a69ec980a64fc08f9f64306 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sat, 23 Dec 2023 21:42:06 +0800 Subject: [PATCH 16/58] Rename clitheme_example.py to clitheme_demo.py --- clitheme_example.py => clitheme_demo.py | 2 ++ 1 file changed, 2 insertions(+) rename clitheme_example.py => clitheme_demo.py (98%) diff --git a/clitheme_example.py b/clitheme_demo.py similarity index 98% rename from clitheme_example.py rename to clitheme_demo.py index 4b9398a..533d0f3 100755 --- a/clitheme_example.py +++ b/clitheme_demo.py @@ -1,5 +1,7 @@ #!/usr/bin/python3 +# This file is originally named clitheme_example.py + import os import sys from src.clitheme import frontend -- Gitee From 0a9d40de982dd62de1a801e1c9a0d02d52ffabda Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sun, 24 Dec 2023 14:19:22 +0800 Subject: [PATCH 17/58] Change data directory for Windows --- src/clitheme/_globalvar.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/clitheme/_globalvar.py b/src/clitheme/_globalvar.py index 39e2c07..022ef9c 100644 --- a/src/clitheme/_globalvar.py +++ b/src/clitheme/_globalvar.py @@ -7,26 +7,25 @@ try: from . import _version except ImportError: import _version clitheme_root_data_path="" -if os.name=="nt": # Windows - try: - clitheme_root_data_path=os.environ["LOCALAPPDATA"]+"\\clitheme" - except KeyError: None -else: +if os.name=="posix": # Linux/macOS only try: clitheme_root_data_path=os.environ["XDG_DATA_HOME"]+"/clitheme" except KeyError: None if clitheme_root_data_path=="": # prev did not succeed try: - if os.name=="nt": - clitheme_root_data_path=os.environ["USERPROFILE"]+"\\AppData\\Local\\clitheme" + if os.name=="nt": # Windows + clitheme_root_data_path=os.environ["USERPROFILE"]+"\\.local\\share\\clitheme" else: if not os.environ['HOME'].startswith('/'): # sanity check raise KeyError clitheme_root_data_path=os.environ["HOME"]+"/.local/share/clitheme" except KeyError: print("[clitheme] Error: unable to get your home directory or invalid home directory information") - print("Please make sure that the $HOME environment variable is set correctly.") + if os.name=="nt": + print(r"Please make sure that the %USERPROFILE% environment variable is set correctly") + else: + print("Please make sure that the $HOME environment variable is set correctly.") print("Try restarting your terminal session to fix this issue.") exit(1) clitheme_temp_root="/tmp" -- Gitee From fd65cb871220db8eb338e42a0ab98e7ab7b54761 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sun, 24 Dec 2023 23:44:34 +0800 Subject: [PATCH 18/58] Update version (20231224) --- debian/changelog | 4 ++-- src/clitheme/_version.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index 86dd753..d540ba2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ -clitheme (1.1-dev20231223-1) experimental; urgency=low +clitheme (1.1-dev20231224-1) experimental; urgency=low * In development, please see commit logs for changes - -- swiftycode <3291929745@qq.com> Sat, 23 Dec 2023 18:01:24 +0800 + -- swiftycode <3291929745@qq.com> Sun, 24 Dec 2023 23:43:00 +0800 clitheme (1.0-r2-1) unstable; urgency=medium diff --git a/src/clitheme/_version.py b/src/clitheme/_version.py index e1bc8e8..7460695 100644 --- a/src/clitheme/_version.py +++ b/src/clitheme/_version.py @@ -1,10 +1,10 @@ # Version definition file; define the package version here # The __version__ variable must be a literal string; DO NOT use variables -__version__="1.1-dev20231223" +__version__="1.1-dev20231224" major=1 minor=1 release=0 # 0 stands for "dev" # For PKGBUILD # version_main CANNOT contain hyphens (-); use underscores (_) instead -version_main="1.1_dev20231223" +version_main="1.1_dev20231224" version_buildnumber=1 \ No newline at end of file -- Gitee From 6401b8b7c56cbe30be6e7183d93be9baa0429310 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Mon, 25 Dec 2023 22:21:10 +0800 Subject: [PATCH 19/58] Make example-clithemedef/README look better --- example-clithemedef/README.zh-CN.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/example-clithemedef/README.zh-CN.md b/example-clithemedef/README.zh-CN.md index 722fe5b..d05e345 100644 --- a/example-clithemedef/README.zh-CN.md +++ b/example-clithemedef/README.zh-CN.md @@ -4,37 +4,37 @@ --- -以下字符串会在`install-files`和`install-file`指令输出中用到: +**以下字符串会在`install-files`和`install-file`指令输出中用到:** -`com.example example-app found-file` +### `com.example example-app found-file` > 在当前目录找到了{}个文件 -`com.example example-app installing-file` +### `com.example example-app installing-file` > -> 正在安装 "{}"... -`com.example example-app install-success` +### `com.example example-app install-success` > 已成功安装{}个文件 该文本会被`install-files`指令输出调用。 -`com.example example-app install-success-file` +### `com.example example-app install-success-file` > 已成功安装"{}" 该文本会被`install-file`指令输出调用。 -`com.example example-app file-not-found` +### `com.example example-app file-not-found` > 错误:找不到文件"{}" -`com.example example-app format-error` +### `com.example example-app format-error` > 错误:命令语法不正确 -`com.example example-app directory-empty` +### `com.example example-app directory-empty` > 错误:当前目录里没有任何文件 @@ -42,20 +42,20 @@ --- -以下字符串会在帮助信息中用到: +**以下字符串会在帮助信息中用到:** -`com.example example-app helpmessage description-general` +### `com.example example-app helpmessage description-general` > 文件安装程序样例(不会修改系统中的文件) 该文本提供应用程序的名称,会在第一行显示。 -`com.example example-app helpmessage description-usageprompt` +### `com.example example-app helpmessage description-usageprompt` > 使用方法: 你可以通过此字符串定义”使用方法“的输出样式,会在命令列表前一行显示。 -`com.example example-app helpmessage unknown-command` +### `com.example example-app helpmessage unknown-command` > 错误:未知命令"{}" \ No newline at end of file -- Gitee From eb09b80efcfd5aa5ebb2d90f4884188a6c3358ff Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Wed, 27 Dec 2023 22:23:40 +0800 Subject: [PATCH 20/58] Rename README.zh-CN to README --- README.zh-CN.md => README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README.zh-CN.md => README.md (100%) diff --git a/README.zh-CN.md b/README.md similarity index 100% rename from README.zh-CN.md rename to README.md -- Gitee From 8d3a635bfe931f119119d7b7a7d41df975855af6 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Wed, 27 Dec 2023 22:56:04 +0800 Subject: [PATCH 21/58] Add more information to README --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4ab0a93..0de7fcb 100644 --- a/README.md +++ b/README.md @@ -251,4 +251,8 @@ rm -rf buildtmp srctmp ## 更多信息 -更多的详细信息和文档请参考本项目Wiki页面。 +- 更多的详细信息和文档请参考本项目Wiki页面:https://gitee.com/swiftycode/clitheme/wikis/pages +- 欢迎通过Issues和Pull Requests提交建议和改进。 +- 本仓库中的代码也同步在GitHub上:https://github.com/swiftycode256/clitheme + - GitHub仓库上只包含仓库代码,不包含新版本公告和发行版信息。 + - 不建议在GitHub仓库上提交Issues和Pull Requests,因为我可能不会及时回复。 -- Gitee From 69c9b0fbf065fb297a5cfafc80e7b19e6c0d3e9a Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sat, 30 Dec 2023 00:52:41 +0800 Subject: [PATCH 22/58] Support specifying multiple file on apply-theme --- src/clitheme/cli.py | 58 +++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/src/clitheme/cli.py b/src/clitheme/cli.py index 6f74f1b..4022151 100755 --- a/src/clitheme/cli.py +++ b/src/clitheme/cli.py @@ -23,9 +23,9 @@ usage_description=\ {0} --help {0} --version""" -def apply_theme(file_content: str, overlay: bool, preserve_temp=False): +def apply_theme(file_contents: list[str], overlay: bool, preserve_temp=False): """ - Apply the theme using the provided definition file content. + Apply the theme using the provided definition file contents in a list[str] object. - Set overlay=True to overlay the theme on top of existing theme[s] - Set preserve_temp=True to preserve the temp directory (debugging purposes) @@ -50,12 +50,18 @@ def apply_theme(file_content: str, overlay: bool, preserve_temp=False): _generator.generate_custom_path() shutil.copytree(_globalvar.clitheme_root_data_path, _generator.path) generate_path=False - # Generate data hierarchy, erase current data, copy it to data path - try: - _generator.generate_data_hierarchy(file_content, custom_path_gen=generate_path,custom_infofile_name=str(index)) - except SyntaxError: - print("An error occurred while generating the data:\n{}".format(str(sys.exc_info()[1]))) - return 1 + for i in range(len(file_contents)): + if len(file_contents)>1: print(" > Processing file {}...".format(str(i+1))) + file_content=file_contents[i] + # Generate data hierarchy, erase current data, copy it to data path + try: + _generator.generate_data_hierarchy(file_content, custom_path_gen=generate_path,custom_infofile_name=str(index)) + generate_path=False # Don't generate another temp folder after first one + index+=1 + except SyntaxError: + print("[File {}] An error occurred while generating the data:\n{}".format(str(i+1), str(sys.exc_info()[1]))) + return 1 + if len(file_contents)>1: print(" > All finished") print("Successfully generated data") if preserve_temp: if os.name=="nt": @@ -120,7 +126,7 @@ def unset_current_theme(): """ try: shutil.rmtree(_globalvar.clitheme_root_data_path) except FileNotFoundError: - print("No theme data present (no theme was set)") + print("Error: No theme data present (no theme was set)") return 1 except Exception: print("An error occurred while removing the data:\n{}".format(str(sys.exc_info()[1]))) @@ -214,7 +220,7 @@ def main(cli_args): if cli_args[1]=="apply-theme": if len(cli_args)<3: return handle_usage_error("Error: not enough arguments", arg_first) - path="" + paths=[] overlay=False preserve_temp=False for arg in cli_args[2:]: @@ -223,16 +229,28 @@ def main(cli_args): elif arg.strip()=="--preserve-temp": preserve_temp=True else: return handle_usage_error("Unknown option \"{}\"".format(arg), arg_first) else: - if path!="": # already specified path - return handle_usage_error("Error: too many arguments", arg_first) - path=arg - contents="" - try: - contents=open(path, 'r', encoding="utf-8").read() - except Exception: - print("An error occurred while reading the file: \n{}".format(str(sys.exc_info()[1]))) - return 1 - return apply_theme(contents, overlay=overlay, preserve_temp=preserve_temp) + paths.append(arg) + if len(paths)>1 or True: # currently set to True for now + print("The following definition files will be applied in the following order: ") + for i in range(len(paths)): + path=paths[i] + print("\t{}: {}".format(str(i+1), path)) + if os.path.isdir(_globalvar.clitheme_root_data_path) and overlay==False: + print("The existing theme data will be overwritten if you continue.") + if overlay==True: + print("The definition files will be appended on top of the existing theme data.") + inp=input("Do you want to continue? [y/n] ").strip().lower() + if not (inp=="y" or inp=="yes"): + return 1 + content_list=[] + for i in range(len(paths)): + path=paths[i] + try: + content_list.append(open(path, 'r', encoding="utf-8").read()) + except Exception: + print("[File {}] An error occurred while reading the file: \n{}".format(str(i+1), str(sys.exc_info()[1]))) + return 1 + return apply_theme(content_list, overlay=overlay, preserve_temp=preserve_temp) elif cli_args[1]=="get-current-theme-info": if len(cli_args)>2: # disabled additional options return handle_usage_error("Error: too many arguments", arg_first) -- Gitee From 6bb7b2c2074e65eb2aa42eb03c8930fd79440361 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sat, 30 Dec 2023 00:57:30 +0800 Subject: [PATCH 23/58] Update version (20231229) --- debian/changelog | 4 ++-- src/clitheme/_version.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index d540ba2..ab17518 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ -clitheme (1.1-dev20231224-1) experimental; urgency=low +clitheme (1.1-dev20231229-1) UNRELEASED; urgency=low * In development, please see commit logs for changes - -- swiftycode <3291929745@qq.com> Sun, 24 Dec 2023 23:43:00 +0800 + -- swiftycode <3291929745@qq.com> Sat, 30 Dec 2023 00:54:28 +0800 clitheme (1.0-r2-1) unstable; urgency=medium diff --git a/src/clitheme/_version.py b/src/clitheme/_version.py index 7460695..e627f86 100644 --- a/src/clitheme/_version.py +++ b/src/clitheme/_version.py @@ -1,10 +1,10 @@ # Version definition file; define the package version here # The __version__ variable must be a literal string; DO NOT use variables -__version__="1.1-dev20231224" +__version__="1.1-dev20231229" major=1 minor=1 release=0 # 0 stands for "dev" # For PKGBUILD # version_main CANNOT contain hyphens (-); use underscores (_) instead -version_main="1.1_dev20231224" +version_main="1.1_dev20231229" version_buildnumber=1 \ No newline at end of file -- Gitee From a2735c8316640884ee448e91787065dd9561be8c Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sat, 30 Dec 2023 18:24:03 +0800 Subject: [PATCH 24/58] Support specifying multiple files on generate-data-hierarchy --- src/clitheme/cli.py | 92 +++++++++++---------------------------------- 1 file changed, 22 insertions(+), 70 deletions(-) diff --git a/src/clitheme/cli.py b/src/clitheme/cli.py index 4022151..eba0bf4 100755 --- a/src/clitheme/cli.py +++ b/src/clitheme/cli.py @@ -23,12 +23,13 @@ usage_description=\ {0} --help {0} --version""" -def apply_theme(file_contents: list[str], overlay: bool, preserve_temp=False): +def apply_theme(file_contents: list[str], overlay: bool, preserve_temp=False, generate_only=False): """ Apply the theme using the provided definition file contents in a list[str] object. - Set overlay=True to overlay the theme on top of existing theme[s] - Set preserve_temp=True to preserve the temp directory (debugging purposes) + - Set generate_only=True to generate the data hierarchy only (and not apply the theme) """ if overlay: print("Overlay specified") print("==> Generating data...") @@ -63,11 +64,14 @@ def apply_theme(file_contents: list[str], overlay: bool, preserve_temp=False): return 1 if len(file_contents)>1: print(" > All finished") print("Successfully generated data") - if preserve_temp: + if preserve_temp or generate_only: if os.name=="nt": print("View at {}".format(re.sub(r"/", r"\\", _generator.path))) # make the output look pretty else: print("View at {}".format(_generator.path)) + if generate_only: return 0 + # ---Stop here if generate_only is set--- + print("==> Applying theme...") # remove the current data, ignoring directory not found error try: shutil.rmtree(_globalvar.clitheme_root_data_path) @@ -83,43 +87,6 @@ def apply_theme(file_contents: list[str], overlay: bool, preserve_temp=False): except Exception: None return 0 -def generate_data_hierarchy(file_content: str, overlay: bool): - """ - Generate the data hierarchy at the temporary directory (debugging purposes only) - """ - if overlay: print("Overlay specified") - print("==> Generating data...") - index=1 - generate_path=True - if overlay: - # Check if current data exists - if not os.path.isfile(_globalvar.clitheme_root_data_path+"/"+_globalvar.generator_info_pathname+"/"+_globalvar.generator_index_filename): - print("Error: no theme set or the current data is corrupt") - print("Try setting a theme first") - return 1 - # update index - try: index=int(open(_globalvar.clitheme_root_data_path+"/"+_globalvar.generator_info_pathname+"/"+_globalvar.generator_index_filename,'r', encoding="utf-8").read().strip())+1 - except ValueError: - print("Error: the current data is corrupt") - print("Remove the current theme, set the theme, and try again") - return 1 - # copy the current data into the temp directory - _generator.generate_custom_path() - shutil.copytree(_globalvar.clitheme_root_data_path, _generator.path) - generate_path=False - # Generate data hierarchy, erase current data, copy it to data path - try: - _generator.generate_data_hierarchy(file_content, custom_path_gen=generate_path,custom_infofile_name=str(index)) - except SyntaxError: - print("Error\nAn error occurred while generating the data:\n{}".format(str(sys.exc_info()[1]))) - return 1 - print("Successfully generated data") - if os.name=="nt": - print("View at {}".format(re.sub(r"/", r"\\", _generator.path))) # make the output look pretty - else: - print("View at {}".format(_generator.path)) - return 0 - def unset_current_theme(): """ Delete the current theme data hierarchy from the data path @@ -217,31 +184,36 @@ def main(cli_args): print("Error: no command or option specified") return 1 - if cli_args[1]=="apply-theme": + if cli_args[1]=="apply-theme" or cli_args[1]=="generate-data-hierarchy": if len(cli_args)<3: return handle_usage_error("Error: not enough arguments", arg_first) + generate_only=(cli_args[1]=="generate-data-hierarchy") paths=[] overlay=False preserve_temp=False for arg in cli_args[2:]: if is_option(arg): if arg.strip()=="--overlay": overlay=True - elif arg.strip()=="--preserve-temp": preserve_temp=True + elif arg.strip()=="--preserve-temp" and not generate_only: preserve_temp=True else: return handle_usage_error("Unknown option \"{}\"".format(arg), arg_first) else: paths.append(arg) if len(paths)>1 or True: # currently set to True for now - print("The following definition files will be applied in the following order: ") + if generate_only: + print("The theme data will be generated from the following definition files in the following order:") + else: + print("The following definition files will be applied in the following order: ") for i in range(len(paths)): path=paths[i] print("\t{}: {}".format(str(i+1), path)) - if os.path.isdir(_globalvar.clitheme_root_data_path) and overlay==False: - print("The existing theme data will be overwritten if you continue.") - if overlay==True: - print("The definition files will be appended on top of the existing theme data.") - inp=input("Do you want to continue? [y/n] ").strip().lower() - if not (inp=="y" or inp=="yes"): - return 1 + if not generate_only: + if os.path.isdir(_globalvar.clitheme_root_data_path) and overlay==False: + print("The existing theme data will be overwritten if you continue.") + if overlay==True: + print("The definition files will be appended on top of the existing theme data.") + inp=input("Do you want to continue? [y/n] ").strip().lower() + if not (inp=="y" or inp=="yes"): + return 1 content_list=[] for i in range(len(paths)): path=paths[i] @@ -250,7 +222,7 @@ def main(cli_args): except Exception: print("[File {}] An error occurred while reading the file: \n{}".format(str(i+1), str(sys.exc_info()[1]))) return 1 - return apply_theme(content_list, overlay=overlay, preserve_temp=preserve_temp) + return apply_theme(content_list, overlay=overlay, preserve_temp=preserve_temp, generate_only=generate_only) elif cli_args[1]=="get-current-theme-info": if len(cli_args)>2: # disabled additional options return handle_usage_error("Error: too many arguments", arg_first) @@ -259,26 +231,6 @@ def main(cli_args): if len(cli_args)>2: return handle_usage_error("Error: too many arguments", arg_first) return unset_current_theme() - elif cli_args[1]=="generate-data-hierarchy": - if len(cli_args)<3: - return handle_usage_error("Error: not enough arguments", arg_first) - path="" - overlay=False - for arg in cli_args[2:]: - if is_option(arg): - if arg.strip()=="--overlay": overlay=True - else: return handle_usage_error("Unknown option \"{}\"".format(arg), arg_first) - else: - if path!="": # already specified path - return handle_usage_error("Error: too many arguments", arg_first) - path=arg - contents="" - try: - contents=open(path, 'r', encoding="utf-8").read() - except Exception: - print("An error occurred while reading the file: \n{}".format(str(sys.exc_info()[1]))) - return 1 - return generate_data_hierarchy(contents, overlay=overlay) elif cli_args[1]=="--version": print("clitheme version {0}".format(_globalvar.clitheme_version)) else: -- Gitee From 5e066f44ab61374671046f70d151048f4dad1f50 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sat, 30 Dec 2023 18:44:02 +0800 Subject: [PATCH 25/58] Rename generate-data-hierarchy to generate-data --- docs/clitheme.1 | 10 +++++----- src/clitheme/cli.py | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/clitheme.1 b/docs/clitheme.1 index 3d0c5b4..b48338e 100644 --- a/docs/clitheme.1 +++ b/docs/clitheme.1 @@ -7,11 +7,11 @@ clitheme \- frontend to customize output of applications clitheme is a framework for applications that allows users to customize its output and messages through theme definition files. This CLI interface allows the user to control their current settings and theme definition on the system. .SH OPTIONS .P -.B apply-theme [themedef-file] [--overlay] [--preserve-temp] +.B apply-theme [themedef-file(s)] [--overlay] [--preserve-temp] .RS 7 -Applies a given theme definition file into the current system. Supported applications will immediately start using the defined values after performing this operation. +Applies the given theme definition file(s) into the current system. Supported applications will immediately start using the defined values after performing this operation. -Specify \fB--overlay\fR to append value definitions in the file onto the current data. +Specify \fB--overlay\fR to append value definitions in the file(s) onto the current data. Specify \fB--preserve-temp\fR to prevent the temporary directory from removed after the operation. .RE @@ -26,9 +26,9 @@ Outputs detailed information about the currently applied theme. If multiple them Removes the current theme data from the system. Supported applications will immediately stop using the defined values after this operation. .RE .P -.B generate-data-hierarchy [themedef-file] [--overlay] +.B generate-data [themedef-file(s)] [--overlay] .RS 7 -Generates the data hierarchy for a given theme definition file. This operation generates the same data as \fBapply-theme\fR, but does not apply it onto the system. +Generates the data hierarchy for the given theme definition file(s). This operation generates the same data as \fBapply-theme\fR, but does not apply it onto the system. This command is for debug purposes only. .RE diff --git a/src/clitheme/cli.py b/src/clitheme/cli.py index eba0bf4..8d8108f 100755 --- a/src/clitheme/cli.py +++ b/src/clitheme/cli.py @@ -19,7 +19,7 @@ usage_description=\ """Usage: {0} apply-theme [themedef-file] [--overlay] [--preserve-temp] {0} get-current-theme-info {0} unset-current-theme - {0} generate-data-hierarchy [themedef-file] [--overlay] + {0} generate-data [themedef-file] [--overlay] {0} --help {0} --version""" @@ -138,7 +138,7 @@ def get_current_theme_info(): print(description) # locales locales="(Unknown)" - # version 2: items are seperated by newlines instead of spaces + # version 2: items are separated by newlines instead of spaces if os.path.isfile(target_path+"/"+"clithemeinfo_locales_v2"): locales=open(target_path+"/"+"clithemeinfo_locales_v2", 'r', encoding="utf-8").read().strip() print("Supported locales:") @@ -184,10 +184,10 @@ def main(cli_args): print("Error: no command or option specified") return 1 - if cli_args[1]=="apply-theme" or cli_args[1]=="generate-data-hierarchy": + if cli_args[1]=="apply-theme" or cli_args[1]=="generate-data" or cli_args[1]=="generate-data-hierarchy": if len(cli_args)<3: return handle_usage_error("Error: not enough arguments", arg_first) - generate_only=(cli_args[1]=="generate-data-hierarchy") + generate_only=(cli_args[1]=="generate-data" or cli_args[1]=="generate-data-hierarchy") paths=[] overlay=False preserve_temp=False -- Gitee From 4f942cc4fba7f505108c04241109f9932d7c4555 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sun, 31 Dec 2023 00:07:05 +0800 Subject: [PATCH 26/58] Update version (20231230) --- debian/changelog | 4 ++-- src/clitheme/_version.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index ab17518..96d0f41 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ -clitheme (1.1-dev20231229-1) UNRELEASED; urgency=low +clitheme (1.1-dev20231230-1) UNRELEASED; urgency=low * In development, please see commit logs for changes - -- swiftycode <3291929745@qq.com> Sat, 30 Dec 2023 00:54:28 +0800 + -- swiftycode <3291929745@qq.com> Sun, 31 Dec 2023 00:04:57 +0800 clitheme (1.0-r2-1) unstable; urgency=medium diff --git a/src/clitheme/_version.py b/src/clitheme/_version.py index e627f86..67a95db 100644 --- a/src/clitheme/_version.py +++ b/src/clitheme/_version.py @@ -1,10 +1,10 @@ # Version definition file; define the package version here # The __version__ variable must be a literal string; DO NOT use variables -__version__="1.1-dev20231229" +__version__="1.1-dev20231230" major=1 minor=1 release=0 # 0 stands for "dev" # For PKGBUILD # version_main CANNOT contain hyphens (-); use underscores (_) instead -version_main="1.1_dev20231229" +version_main="1.1_dev20231230" version_buildnumber=1 \ No newline at end of file -- Gitee From 909a6895438b6bbfd4de68199e4e33f9a76dbb26 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sun, 31 Dec 2023 22:20:29 +0800 Subject: [PATCH 27/58] Improve language detection in frontend --- src/clitheme/frontend.py | 46 +++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/src/clitheme/frontend.py b/src/clitheme/frontend.py index ac9dd4a..cf589f5 100644 --- a/src/clitheme/frontend.py +++ b/src/clitheme/frontend.py @@ -81,23 +81,49 @@ class FetchDescriptor(): if self.debug_mode: print("Error: entry names/subsections {}".format(_globalvar.sanity_check_error_message)) return fallback_string lang="" - lang_without_encoding="" + # Language handling: see https://www.gnu.org/software/gettext/manual/gettext.html#Locale-Environment-Variables for more information if not self.disable_lang: if self.lang!="": lang=self.lang - elif os.environ.__contains__("LANG"): - lang=os.environ["LANG"] - if lang.strip()!="": # not empty - for char in lang: - if char=='.': # if reaches e.g. ".UTF-8" section - break - lang_without_encoding+=char - if self.debug_mode: print("[Debug]", lang, lang_without_encoding, entry_path) + else: + # $LANGUAGE (list of languages separated by colons) + if os.environ.__contains__("LANGUAGE"): + target_str=os.environ['LANGUAGE'] + for each_language in target_str.strip().split(":"): + # avoid exploit of accessing top-level folders + if each_language.startswith("."): continue + # Ignore en and en_US (See https://wiki.archlinux.org/title/Locale#LANGUAGE:_fallback_locales) + if each_language!="en" and each_language!="en_US": + # Treat C as en_US also + if re.sub(r"(?P.+)[\.].+", r"\g", each_language)=="C": + lang+=re.sub(r".+[\.]", "en_US.", each_language)+" " + lang+="en_US"+" " + lang+=each_language+" " + # no encoding + lang+=re.sub(r"(?P.+)[\.].+", r"\g", each_language)+" " + lang=lang.strip() + # $LC_ALL + elif os.environ.__contains__("LC_ALL"): + target_str=os.environ["LC_ALL"].strip() + if not target_str.startswith("."): + lang=target_str+" " + lang+=re.sub(r"(?P.+)[\.].+", r"\g", target_str) + # $LANG + elif os.environ.__contains__("LANG"): + target_str=os.environ["LANG"].strip() + if not target_str.startswith("."): + lang=target_str+" " + lang+=re.sub(r"(?P.+)[\.].+", r"\g", target_str) + + if self.debug_mode: print("[Debug]", lang, entry_path) path=data_path+"/"+self.domain_name+"/"+self.app_name+"/"+self.subsections for section in entry_path.split(): path+="/"+section # path with lang, path with lang but without e.g. .UTF-8, path with no lang - possible_paths=[path+"__"+lang, path+"__"+lang_without_encoding, path] + possible_paths=[] + for l in lang.split(): + possible_paths.append(path+"__"+l) + possible_paths.append(path) for p in possible_paths: if self.debug_mode: print("Trying "+p, end="...") try: -- Gitee From 518677977d73c3350dc733cad827b1e244b71a5f Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Mon, 1 Jan 2024 00:29:45 +0800 Subject: [PATCH 28/58] Support specifying mutiple locales in locale_block --- clitheme-testblock_testprogram.py | 15 ++++++++++++++- src/clitheme/_generator.py | 13 +++++++------ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/clitheme-testblock_testprogram.py b/clitheme-testblock_testprogram.py index a8258cf..5af2059 100644 --- a/clitheme-testblock_testprogram.py +++ b/clitheme-testblock_testprogram.py @@ -10,7 +10,7 @@ end_header begin_main entry test_entry - locale_block default + locale_block default en_US en C this @@ -52,5 +52,18 @@ f.disable_lang=False f.lang="zh_CN" print(f.reof("test_entry", "Nonexistent")) +for lang in ["C", "en", "en_US", "zh_CN"]: + f.disable_lang=True + name=f"test_entry__{lang}" + if f.entry_exists(name): + print(f"{name} OK") + else: + print(f"{name} not found") + +import sys +if sys.argv.__contains__("--preserve-temp"): + print(f"View generated data at {_generator.path}") + exit() + import shutil shutil.rmtree(_generator.path) \ No newline at end of file diff --git a/src/clitheme/_generator.py b/src/clitheme/_generator.py index 67060b9..983d98f 100644 --- a/src/clitheme/_generator.py +++ b/src/clitheme/_generator.py @@ -117,10 +117,11 @@ def generate_data_hierarchy(file_content, custom_path_gen=True, custom_infofile_ pattern=r"(?P\n|^)[ ]{"+str(blockinput_minspaces)+"}" blockinput_data=re.sub(pattern,r"\g", blockinput_data) if current_status=="entry": - target_entry=current_entry_name - if current_entry_locale!="default": - target_entry+="__"+current_entry_locale - add_entry(datapath,target_entry, blockinput_data, current_entry_linenumber) + for this_locale in current_entry_locale.split(): + target_entry=current_entry_name + if this_locale!="default": + target_entry+="__"+this_locale + add_entry(datapath,target_entry, blockinput_data, current_entry_linenumber) # clear data current_entry_locale="" current_entry_linenumber=-1 @@ -272,9 +273,9 @@ def generate_data_hierarchy(file_content, custom_path_gen=True, custom_infofile_ target_entry+="__"+phrases[1] add_entry(datapath,target_entry,content,linenumber) elif phrases[0]=="locale_block": - if len(phrases)!=2: + if len(phrases)<2: handle_error("Format error in {} at line {}".format(phrases[0],linenumber)) - current_entry_locale=phrases[1] + current_entry_locale=splitarray_to_string(phrases[1:]) current_entry_linenumber=linenumber blockinput=True # start block input elif phrases[0]=="end_entry": -- Gitee From 62ae0d72f0568a07245cd6739eef2102d44be8d1 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Mon, 1 Jan 2024 00:35:25 +0800 Subject: [PATCH 29/58] Improve debug message output --- src/clitheme/frontend.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/clitheme/frontend.py b/src/clitheme/frontend.py index cf589f5..510cb53 100644 --- a/src/clitheme/frontend.py +++ b/src/clitheme/frontend.py @@ -84,8 +84,10 @@ class FetchDescriptor(): # Language handling: see https://www.gnu.org/software/gettext/manual/gettext.html#Locale-Environment-Variables for more information if not self.disable_lang: if self.lang!="": + if self.debug_mode: print("[Debug] Locale: Using defined self.lang") lang=self.lang else: + if self.debug_mode: print("[Debug] Locale: Using environment variables") # $LANGUAGE (list of languages separated by colons) if os.environ.__contains__("LANGUAGE"): target_str=os.environ['LANGUAGE'] @@ -115,7 +117,8 @@ class FetchDescriptor(): lang=target_str+" " lang+=re.sub(r"(?P.+)[\.].+", r"\g", target_str) - if self.debug_mode: print("[Debug]", lang, entry_path) + if self.debug_mode: print(f"[Debug] lang: {lang}\n[Debug] entry_path: {entry_path}") + # just being lazy here I don't want to check the variables before using ಥ_ಥ (because it doesn't matter) path=data_path+"/"+self.domain_name+"/"+self.app_name+"/"+self.subsections for section in entry_path.split(): path+="/"+section -- Gitee From 401d7442b15a7c96359e4b8aa692ba65c3f7d548 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Mon, 1 Jan 2024 00:39:41 +0800 Subject: [PATCH 30/58] Improve whitespace trimming of frontend.FetchDescriptor arguments --- src/clitheme/frontend.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/clitheme/frontend.py b/src/clitheme/frontend.py index 510cb53..bb66333 100644 --- a/src/clitheme/frontend.py +++ b/src/clitheme/frontend.py @@ -37,24 +37,24 @@ class FetchDescriptor(): # Leave domain and app names blank for global reference if domain_name==None: - self.domain_name=global_domain + self.domain_name=global_domain.strip() else: self.domain_name=domain_name.strip() if app_name==None: - self.app_name=global_appname + self.app_name=global_appname.strip() else: self.app_name=app_name.strip() if subsections==None: - self.subsections=global_subsections + self.subsections=global_subsections.strip() else: self.subsections=subsections.strip() if lang==None: - self.lang=global_lang + self.lang=global_lang.strip() else: - self.lang=lang + self.lang=lang.strip() if debug_mode==None: self.debug_mode=global_debugmode -- Gitee From ef70a8b08b5b6a3162504d6baf20a1febf1e5b77 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Mon, 1 Jan 2024 00:41:33 +0800 Subject: [PATCH 31/58] Update version (20231231) --- debian/changelog | 4 ++-- src/clitheme/_version.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index 96d0f41..60cbef7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ -clitheme (1.1-dev20231230-1) UNRELEASED; urgency=low +clitheme (1.1-dev20231231-1) UNRELEASED; urgency=low * In development, please see commit logs for changes - -- swiftycode <3291929745@qq.com> Sun, 31 Dec 2023 00:04:57 +0800 + -- swiftycode <3291929745@qq.com> Mon, 01 Jan 2024 00:40:16 +0800 clitheme (1.0-r2-1) unstable; urgency=medium diff --git a/src/clitheme/_version.py b/src/clitheme/_version.py index 67a95db..83a09d4 100644 --- a/src/clitheme/_version.py +++ b/src/clitheme/_version.py @@ -1,10 +1,10 @@ # Version definition file; define the package version here # The __version__ variable must be a literal string; DO NOT use variables -__version__="1.1-dev20231230" +__version__="1.1-dev20231231" major=1 minor=1 release=0 # 0 stands for "dev" # For PKGBUILD # version_main CANNOT contain hyphens (-); use underscores (_) instead -version_main="1.1_dev20231230" +version_main="1.1_dev20231231" version_buildnumber=1 \ No newline at end of file -- Gitee From 4eced9ab7d8854d7932029c95f84be6305e08b18 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Mon, 1 Jan 2024 01:07:14 +0800 Subject: [PATCH 32/58] Improve locale sanity checking --- src/clitheme/frontend.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/clitheme/frontend.py b/src/clitheme/frontend.py index bb66333..49cfece 100644 --- a/src/clitheme/frontend.py +++ b/src/clitheme/frontend.py @@ -85,7 +85,10 @@ class FetchDescriptor(): if not self.disable_lang: if self.lang!="": if self.debug_mode: print("[Debug] Locale: Using defined self.lang") - lang=self.lang + if not _globalvar.sanity_check(self.lang)==False: + lang=self.lang + else: + if self.debug_mode: print("[Debug] Locale: sanity check failed") else: if self.debug_mode: print("[Debug] Locale: Using environment variables") # $LANGUAGE (list of languages separated by colons) @@ -93,7 +96,7 @@ class FetchDescriptor(): target_str=os.environ['LANGUAGE'] for each_language in target_str.strip().split(":"): # avoid exploit of accessing top-level folders - if each_language.startswith("."): continue + if _globalvar.sanity_check(each_language)==False: continue # Ignore en and en_US (See https://wiki.archlinux.org/title/Locale#LANGUAGE:_fallback_locales) if each_language!="en" and each_language!="en_US": # Treat C as en_US also @@ -107,15 +110,19 @@ class FetchDescriptor(): # $LC_ALL elif os.environ.__contains__("LC_ALL"): target_str=os.environ["LC_ALL"].strip() - if not target_str.startswith("."): + if not _globalvar.sanity_check(target_str)==False: lang=target_str+" " lang+=re.sub(r"(?P.+)[\.].+", r"\g", target_str) + else: + if self.debug_mode: print("[Debug] Locale: sanity check failed") # $LANG elif os.environ.__contains__("LANG"): target_str=os.environ["LANG"].strip() - if not target_str.startswith("."): + if not _globalvar.sanity_check(target_str)==False: lang=target_str+" " lang+=re.sub(r"(?P.+)[\.].+", r"\g", target_str) + else: + if self.debug_mode: print("[Debug] Locale: sanity check failed") if self.debug_mode: print(f"[Debug] lang: {lang}\n[Debug] entry_path: {entry_path}") # just being lazy here I don't want to check the variables before using ಥ_ಥ (because it doesn't matter) -- Gitee From 9e4801ca0390c5ef95f50e698a2b77552ea671e3 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Mon, 1 Jan 2024 17:26:18 +0800 Subject: [PATCH 33/58] Support setting local definition file --- clitheme-testblock_testprogram.py | 15 ++++++---- clitheme_fallback.py | 30 ++++++++++++------- src/clitheme/frontend.py | 49 ++++++++++++++++++++++++++++++- 3 files changed, 76 insertions(+), 18 deletions(-) diff --git a/clitheme-testblock_testprogram.py b/clitheme-testblock_testprogram.py index 5af2059..b18aa13 100644 --- a/clitheme-testblock_testprogram.py +++ b/clitheme-testblock_testprogram.py @@ -1,7 +1,7 @@ #!/usr/bin/python3 # Program for testing multi-line (block) processing of _generator -from src.clitheme import _generator, frontend, _globalvar +from src.clitheme import _generator, frontend file_data=""" begin_header @@ -41,17 +41,20 @@ begin_main end_main """ -_generator.generate_data_hierarchy(file_data) -frontend.data_path=_generator.path+"/"+_globalvar.generator_data_pathname +frontend.global_debugmode=True +if frontend.set_local_themedef(file_data)==False: + print("Error: set_local_themedef failed") + exit(1) f=frontend.FetchDescriptor() print("Default locale:") f.disable_lang=True -print(f.reof("test_entry", "Nonexistent")) +# Not printing because debug mode already prints +(f.reof("test_entry", "Nonexistent")) print("zh_CN locale:") f.disable_lang=False f.lang="zh_CN" -print(f.reof("test_entry", "Nonexistent")) - +(f.reof("test_entry", "Nonexistent")) +f.debug_mode=False for lang in ["C", "en", "en_US", "zh_CN"]: f.disable_lang=True name=f"test_entry__{lang}" diff --git a/clitheme_fallback.py b/clitheme_fallback.py index 7a4754d..b21a553 100644 --- a/clitheme_fallback.py +++ b/clitheme_fallback.py @@ -1,29 +1,37 @@ """ -clitheme fallback frontend for 1.0 (returns fallback values for all functions) +clitheme fallback frontend for 1.1 (returns fallback values for all functions) """ -import os,sys -import random -import string from typing import Optional +data_path="" + global_domain="" global_appname="" global_subsections="" global_debugmode=False -global_lang="" # Override locale +global_lang="" global_disablelang=False +alt_path=None + +def set_local_themedef(file_content: str) -> bool: + """Fallback set_local_themedef function (always returns False)""" + return False +def unset_local_themedef(): + """Fallback unset_local_themedef function""" + return + class FetchDescriptor(): """ Object containing domain and app information used for fetching entries """ def __init__(self, domain_name: Optional[str] = None, app_name: Optional[str] = None, subsections: Optional[str] = None, lang: Optional[str] = None, debug_mode: Optional[bool] = None, disable_lang: Optional[bool] = None): - """fallback init function""" + """Fallback init function""" return - def retrieve_entry_or_fallback(self, entry_path: str, fallback_string: str) -> str: - """fallback retrieve_entry_or_fallback function (always return fallback string)""" - return fallback_string - reof=retrieve_entry_or_fallback # a shorter alias of the function + def retrieve_entry_or_Fallback(self, entry_path: str, Fallback_string: str) -> str: + """Fallback retrieve_entry_or_Fallback function (always return Fallback string)""" + return Fallback_string + reof=retrieve_entry_or_Fallback # a shorter alias of the function def entry_exists(self, entry_path: str) -> bool: - """fallback entry_exists function (always return false)""" + """Fallback entry_exists function (always return false)""" return False \ No newline at end of file diff --git a/src/clitheme/frontend.py b/src/clitheme/frontend.py index 49cfece..3907a09 100644 --- a/src/clitheme/frontend.py +++ b/src/clitheme/frontend.py @@ -6,11 +6,14 @@ import os,sys import random import string import re +import hashlib from typing import Optional try: from . import _globalvar + from . import _generator except ImportError: # for test program import _globalvar + import _generator data_path=_globalvar.clitheme_root_data_path+"/"+_globalvar.generator_data_pathname global_domain="" @@ -20,6 +23,43 @@ global_debugmode=False global_lang="" # Override locale global_disablelang=False +alt_path=None +# Support for setting a local definition file +# - Generate the data in a temporary directory named after content hash +# - First try alt_path then data_path + +def set_local_themedef(file_content: str) -> bool: + """ + Sets a local theme definition file for the current frontend instance. + When set, the FetchDescriptor functions will try the local definition before falling back to global theme data. + + WARNING: Pass the file content in str to this function; DO NOT pass the path to the file. + + This function returns True if successful, otherwise returns False. + """ + # Determine directory name + h=hashlib.shake_256(bytes(file_content, "utf-8")) + dir_name=f"clitheme-data-{h.hexdigest(6)}" # length of 12 (6*2) + path_name=_globalvar.clitheme_temp_root+"/"+dir_name + if global_debugmode: print("[Debug] "+path_name) + # Generate data hierarchy as needed + if not os.path.exists(path_name): + _generator.path=path_name + try: + _generator.generate_data_hierarchy(file_content, custom_path_gen=False) + except SyntaxError: + if global_debugmode: print("[Debug] Generator error: "+str(sys.exc_info()[1])) + return False + global alt_path + alt_path=path_name+"/"+_globalvar.generator_data_pathname + return True +def unset_local_themedef(): + """ + Unsets the local theme definition file for the current frontend instance. + After this operation, FetchDescriptor functions will no longer use local definitions. + """ + global alt_path; alt_path=None + class FetchDescriptor(): """ Object containing domain and app information used for fetching entries @@ -127,10 +167,17 @@ class FetchDescriptor(): if self.debug_mode: print(f"[Debug] lang: {lang}\n[Debug] entry_path: {entry_path}") # just being lazy here I don't want to check the variables before using ಥ_ಥ (because it doesn't matter) path=data_path+"/"+self.domain_name+"/"+self.app_name+"/"+self.subsections + path2=None + if alt_path!=None: path2=alt_path+"/"+self.domain_name+"/"+self.app_name+"/"+self.subsections for section in entry_path.split(): path+="/"+section + if path2!=None: path2+="/"+section # path with lang, path with lang but without e.g. .UTF-8, path with no lang possible_paths=[] + if path2!=None: + for l in lang.split(): + possible_paths.append(path2+"__"+l) + possible_paths.append(path2) for l in lang.split(): possible_paths.append(path+"__"+l) possible_paths.append(path) @@ -151,7 +198,7 @@ class FetchDescriptor(): def entry_exists(self, entry_path: str) -> bool: """ Check if the entry at the given entry path exists. - Returns true if exists and false if does not exist + Returns true if exists and false if does not exist. """ # just being lazy here I don't want to rewrite this all over again ಥ_ಥ fallback_string="" -- Gitee From bea00a8fe2d9c9b465a809797438b17ec6960c82 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Mon, 1 Jan 2024 23:40:18 +0800 Subject: [PATCH 34/58] Update version (20240101) --- debian/changelog | 4 ++-- src/clitheme/_version.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index 60cbef7..c0550e0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ -clitheme (1.1-dev20231231-1) UNRELEASED; urgency=low +clitheme (1.1-dev20240101-1) UNRELEASED; urgency=low * In development, please see commit logs for changes - -- swiftycode <3291929745@qq.com> Mon, 01 Jan 2024 00:40:16 +0800 + -- swiftycode <3291929745@qq.com> Mon, 01 Jan 2024 23:39:05 +0800 clitheme (1.0-r2-1) unstable; urgency=medium diff --git a/src/clitheme/_version.py b/src/clitheme/_version.py index 83a09d4..765f3fc 100644 --- a/src/clitheme/_version.py +++ b/src/clitheme/_version.py @@ -1,10 +1,10 @@ # Version definition file; define the package version here # The __version__ variable must be a literal string; DO NOT use variables -__version__="1.1-dev20231231" +__version__="1.1-dev20240101" major=1 minor=1 release=0 # 0 stands for "dev" # For PKGBUILD # version_main CANNOT contain hyphens (-); use underscores (_) instead -version_main="1.1_dev20231231" +version_main="1.1_dev20240101" version_buildnumber=1 \ No newline at end of file -- Gitee From 96151fd58d710ca9ae8b9e7c3ef82d3e7c389001 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Thu, 4 Jan 2024 12:55:48 +0800 Subject: [PATCH 35/58] Add format_entry_or_fallback in frontend --- src/clitheme/frontend.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/clitheme/frontend.py b/src/clitheme/frontend.py index 3907a09..557c51e 100644 --- a/src/clitheme/frontend.py +++ b/src/clitheme/frontend.py @@ -195,6 +195,24 @@ class FetchDescriptor(): reof=retrieve_entry_or_fallback # a shorter alias of the function + def format_entry_or_fallback(self, entry_path: str, fallback_string: str, *args, **kwargs) -> str: + """ + Attempt to retrieve and format the entry based on given entry path and arguments. + If the entry does not exist or an error occurs while formatting the entry string, use the provided fallback string instead. + """ + # retrieve the entry + if not self.entry_exists(entry_path): + if self.debug_mode: print("[Debug] Entry not found") + return fallback_string.format(*args, **kwargs) + entry=self.retrieve_entry_or_fallback(entry_path, "") + # format the string + try: + return entry.format(*args, **kwargs) + except Exception: + if self.debug_mode: print("[Debug] Format error: {err}".format(err=str(sys.exc_info()[1]))) + return fallback_string.format(*args, **kwargs) + feof=format_entry_or_fallback # a shorter alias of the function + def entry_exists(self, entry_path: str) -> bool: """ Check if the entry at the given entry path exists. -- Gitee From 6d78b2a3675b5478ed2af5ab20ae87a76498efec Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sat, 6 Jan 2024 15:58:36 +0800 Subject: [PATCH 36/58] Support customizing cli.py output --- src/clitheme/cli.py | 110 ++++++++++++++++++++++++++------------------ 1 file changed, 66 insertions(+), 44 deletions(-) diff --git a/src/clitheme/cli.py b/src/clitheme/cli.py index 8d8108f..7b0e919 100755 --- a/src/clitheme/cli.py +++ b/src/clitheme/cli.py @@ -11,9 +11,11 @@ import re try: from . import _globalvar from . import _generator + from . import frontend except ImportError: import _globalvar import _generator + import frontend usage_description=\ """Usage: {0} apply-theme [themedef-file] [--overlay] [--preserve-temp] @@ -23,6 +25,10 @@ usage_description=\ {0} --help {0} --version""" +frontend.global_domain="swiftycode" +frontend.global_appname="clitheme" +frontend.global_subsections="cli" + def apply_theme(file_contents: list[str], overlay: bool, preserve_temp=False, generate_only=False): """ Apply the theme using the provided definition file contents in a list[str] object. @@ -31,28 +37,30 @@ def apply_theme(file_contents: list[str], overlay: bool, preserve_temp=False, ge - Set preserve_temp=True to preserve the temp directory (debugging purposes) - Set generate_only=True to generate the data hierarchy only (and not apply the theme) """ - if overlay: print("Overlay specified") - print("==> Generating data...") + f=frontend.FetchDescriptor(subsections="cli apply-theme") + if overlay: print(f.reof("overlay-msg", "Overlay specified")) + print(f.reof("generating-data", "==> Generating data...")) index=1 generate_path=True if overlay: # Check if current data exists if not os.path.isfile(_globalvar.clitheme_root_data_path+"/"+_globalvar.generator_info_pathname+"/"+_globalvar.generator_index_filename): - print("Error: no theme set or the current data is corrupt") - print("Try setting a theme first") + print(f.reof("overlay-no-data", \ + "Error: no theme set or the current data is corrupt\nTry setting a theme first")) return 1 # update index try: index=int(open(_globalvar.clitheme_root_data_path+"/"+_globalvar.generator_info_pathname+"/"+_globalvar.generator_index_filename,'r', encoding="utf-8").read().strip())+1 except ValueError: - print("Error: the current data is corrupt") - print("Remove the current theme, set the theme, and try again") + print(f.reof("overlay-data-error", \ + "Error: the current data is corrupt\nRemove the current theme, set the theme, and try again")) return 1 # copy the current data into the temp directory _generator.generate_custom_path() shutil.copytree(_globalvar.clitheme_root_data_path, _generator.path) generate_path=False for i in range(len(file_contents)): - if len(file_contents)>1: print(" > Processing file {}...".format(str(i+1))) + if len(file_contents)>1: + print(" "+f.feof("processing-file", "> Processing file {filename}...", filename=str(i+1))) file_content=file_contents[i] # Generate data hierarchy, erase current data, copy it to data path try: @@ -60,28 +68,34 @@ def apply_theme(file_contents: list[str], overlay: bool, preserve_temp=False, ge generate_path=False # Don't generate another temp folder after first one index+=1 except SyntaxError: - print("[File {}] An error occurred while generating the data:\n{}".format(str(i+1), str(sys.exc_info()[1]))) + print(f.feof("generate-data-error", "[File {index}] An error occurred while generating the data:\n{message}", \ + index=str(i+1), message=str(sys.exc_info()[1]) )) return 1 - if len(file_contents)>1: print(" > All finished") - print("Successfully generated data") + if len(file_contents)>1: + print(" "+f.reof("all-finished", "> All finished")) + print(f.reof("generate-data-success", "Successfully generated data")) if preserve_temp or generate_only: if os.name=="nt": - print("View at {}".format(re.sub(r"/", r"\\", _generator.path))) # make the output look pretty + print(f.feof("view-temp-dir", "View at {path}", path=re.sub(r"/", r"\\", _generator.path))) # make the output look pretty else: - print("View at {}".format(_generator.path)) + print(f.feof("view-temp-dir", "View at {path}", path=_generator.path)) if generate_only: return 0 # ---Stop here if generate_only is set--- - print("==> Applying theme...") + print(f.reof("applying-theme", "==> Applying theme...")) # remove the current data, ignoring directory not found error try: shutil.rmtree(_globalvar.clitheme_root_data_path) except FileNotFoundError: None + except Exception: + print(f.feof("apply-theme-error", "An error occurred while applying the theme:\n{message}", message=str(sys.exc_info()[1]))) + return 1 + try: shutil.copytree(_generator.path, _globalvar.clitheme_root_data_path) except Exception: - print("An error occurred while applying the theme:\n{}".format(str(sys.exc_info()[1]))) + print(f.feof("apply-theme-error", "An error occurred while applying the theme:\n{message}", message=str(sys.exc_info()[1]))) return 1 - print("Theme applied successfully") + print(f.reof("apply-theme-success", "Theme applied successfully")) if not preserve_temp: try: shutil.rmtree(_generator.path) except Exception: None @@ -91,23 +105,25 @@ def unset_current_theme(): """ Delete the current theme data hierarchy from the data path """ + f=frontend.FetchDescriptor(subsections="cli unset-current-theme") try: shutil.rmtree(_globalvar.clitheme_root_data_path) except FileNotFoundError: - print("Error: No theme data present (no theme was set)") + print(f.reof("no-data-found", "Error: No theme data present (no theme was set)")) return 1 except Exception: - print("An error occurred while removing the data:\n{}".format(str(sys.exc_info()[1]))) + print(f.feof("remove-data-error", "An error occurred while removing the data:\n{message}", message=str(sys.exc_info()[1]))) return 1 - print("Successfully removed the current theme data") + print(f.reof("remove-data-success", "Successfully removed the current theme data")) return 0 def get_current_theme_info(): """ Get the current theme info """ + f=frontend.FetchDescriptor(subsections="cli get-current-theme-info") search_path=_globalvar.clitheme_root_data_path+"/"+_globalvar.generator_info_pathname if not os.path.isdir(search_path): - print("No theme currently set") + print(f.reof("no-theme", "No theme currently set")) return 1 lsdir_result=os.listdir(search_path) lsdir_result.sort(reverse=True) # sort by latest installed @@ -115,8 +131,10 @@ def get_current_theme_info(): for x in lsdir_result: if os.path.isdir(search_path+"/"+x): lsdir_num+=1 - if lsdir_num<=1: print("Currently installed theme: ") - else: print("Overlay history (sorted by latest installed):") + if lsdir_num<=1: + print(f.reof("current-theme-msg", "Currently installed theme:")) + else: + print(f.reof("overlay-history-msg", "Overlay history (sorted by latest installed):")) for theme_pathname in lsdir_result: target_path=search_path+"/"+theme_pathname if not os.path.isdir(target_path): continue # skip current_theme_index file @@ -129,48 +147,48 @@ def get_current_theme_info(): version="(Unknown)" if os.path.isfile(target_path+"/"+"clithemeinfo_version"): version=open(target_path+"/"+"clithemeinfo_version", 'r', encoding="utf-8").read().strip() - print("Version: {}".format(version)) + print(f.feof("version-str", "Version: {ver}", ver=version)) # description description="(Unknown)" if os.path.isfile(target_path+"/"+"clithemeinfo_description"): description=open(target_path+"/"+"clithemeinfo_description", 'r', encoding="utf-8").read() - print("Description:") + print(f.reof("description-str", "Description:")) print(description) # locales locales="(Unknown)" # version 2: items are separated by newlines instead of spaces if os.path.isfile(target_path+"/"+"clithemeinfo_locales_v2"): locales=open(target_path+"/"+"clithemeinfo_locales_v2", 'r', encoding="utf-8").read().strip() - print("Supported locales:") + print(f.reof("locales-str", "Supported locales:")) for locale in locales.splitlines(): if locale.strip()!="": - print("• {}".format(locale.strip())) + print(f.feof("list-item", "• {content}", content=locale.strip())) elif os.path.isfile(target_path+"/"+"clithemeinfo_locales"): locales=open(target_path+"/"+"clithemeinfo_locales", 'r', encoding="utf-8").read().strip() print("Supported locales: ") for locale in locales.split(): - print("• {}".format(locale)) + print(f.feof("list-item", "• {content}", content=locale.strip())) # supported_apps supported_apps="(Unknown)" if os.path.isfile(target_path+"/"+"clithemeinfo_supported_apps_v2"): supported_apps=open(target_path+"/"+"clithemeinfo_supported_apps_v2", 'r', encoding="utf-8").read().strip() print("Supported apps: ") for app in supported_apps.splitlines(): - if app.strip()!="": - print("• {}".format(app)) + if app.strip()!="": + print(f.feof("list-item", "• {content}", content=app.strip())) elif os.path.isfile(target_path+"/"+"clithemeinfo_supported_apps"): supported_apps=open(target_path+"/"+"clithemeinfo_supported_apps", 'r', encoding="utf-8").read().strip() print("Supported apps: ") for app in supported_apps.split(): - print("• {}".format(app)) - print() # newline + print(f.feof("list-item", "• {content}", content=app.strip())) return 0 def is_option(arg): return arg.strip()[0:1]=="-" def handle_usage_error(message, cli_args_first): + f=frontend.FetchDescriptor() print(message) - print("Run {0} --help for usage information".format(cli_args_first)) + print(f.feof("help-usage-prompt", "Run {clitheme} --help for usage information", clitheme=cli_args_first)) return 1 def main(cli_args): """ @@ -178,15 +196,16 @@ def main(cli_args): Provide a list of command line arguments to this function through cli_args. """ + f=frontend.FetchDescriptor() arg_first="clitheme" # controls what appears as the command name in messages if len(cli_args)<=1: # no arguments passed print(usage_description.format(arg_first)) - print("Error: no command or option specified") + print(f.reof("no-command", "Error: no command or option specified")) return 1 if cli_args[1]=="apply-theme" or cli_args[1]=="generate-data" or cli_args[1]=="generate-data-hierarchy": if len(cli_args)<3: - return handle_usage_error("Error: not enough arguments", arg_first) + return handle_usage_error(f.reof("not-enough-arguments", "Error: not enough arguments"), arg_first) generate_only=(cli_args[1]=="generate-data" or cli_args[1]=="generate-data-hierarchy") paths=[] overlay=False @@ -195,23 +214,25 @@ def main(cli_args): if is_option(arg): if arg.strip()=="--overlay": overlay=True elif arg.strip()=="--preserve-temp" and not generate_only: preserve_temp=True - else: return handle_usage_error("Unknown option \"{}\"".format(arg), arg_first) + else: return handle_usage_error(f.feof("unknown-option", "Error: unknown option \"{option}\"", option=arg), arg_first) else: paths.append(arg) + fi=frontend.FetchDescriptor(subsections="cli apply-theme") if len(paths)>1 or True: # currently set to True for now if generate_only: - print("The theme data will be generated from the following definition files in the following order:") + print(fi.reof("generate-data-msg", "The theme data will be generated from the following definition files in the following order:")) else: - print("The following definition files will be applied in the following order: ") + print(fi.reof("apply-theme-msg", "The following definition files will be applied in the following order: ")) for i in range(len(paths)): path=paths[i] print("\t{}: {}".format(str(i+1), path)) if not generate_only: if os.path.isdir(_globalvar.clitheme_root_data_path) and overlay==False: - print("The existing theme data will be overwritten if you continue.") + print(fi.reof("overwrite-notice", "The existing theme data will be overwritten if you continue.")) if overlay==True: - print("The definition files will be appended on top of the existing theme data.") - inp=input("Do you want to continue? [y/n] ").strip().lower() + print(fi.reof("overlay-notice", "The definition files will be appended on top of the existing theme data.")) + inpstr=fi.reof("confirm-prompt", "Do you want to continue? [y/n]") + inp=input(inpstr+" ").strip().lower() if not (inp=="y" or inp=="yes"): return 1 content_list=[] @@ -220,24 +241,25 @@ def main(cli_args): try: content_list.append(open(path, 'r', encoding="utf-8").read()) except Exception: - print("[File {}] An error occurred while reading the file: \n{}".format(str(i+1), str(sys.exc_info()[1]))) + print(fi.feof("read-file-error", "[File {index}] An error occurred while reading the file: \n{message}", \ + index=str(i+1), message=str(sys.exc_info()[1]))) return 1 return apply_theme(content_list, overlay=overlay, preserve_temp=preserve_temp, generate_only=generate_only) elif cli_args[1]=="get-current-theme-info": if len(cli_args)>2: # disabled additional options - return handle_usage_error("Error: too many arguments", arg_first) + return handle_usage_error(f.reof("too-many-arguments", "Error: too many arguments"), arg_first) return get_current_theme_info() elif cli_args[1]=="unset-current-theme": if len(cli_args)>2: - return handle_usage_error("Error: too many arguments", arg_first) + return handle_usage_error(f.reof("too-many-arguments", "Error: too many arguments"), arg_first) return unset_current_theme() elif cli_args[1]=="--version": - print("clitheme version {0}".format(_globalvar.clitheme_version)) + print(f.feof("version-str", "clitheme version {ver}", ver=_globalvar.clitheme_version)) else: if cli_args[1]=="--help": print(usage_description.format(arg_first)) else: - return handle_usage_error("Error: unknown command \"{0}\"".format(cli_args[1]), arg_first) + return handle_usage_error(f.feof("unknown-command", "Error: unknown command \"{cmd}\"", cmd=cli_args[1]), arg_first) return 0 def script_main(): # for script exit(main(sys.argv)) -- Gitee From dfaadc0c356e79f16a128a73b6fbea1dec4d9739 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sat, 6 Jan 2024 16:16:23 +0800 Subject: [PATCH 37/58] Support overlay in set_local_themedef --- src/clitheme/frontend.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/clitheme/frontend.py b/src/clitheme/frontend.py index 557c51e..25e9249 100644 --- a/src/clitheme/frontend.py +++ b/src/clitheme/frontend.py @@ -24,22 +24,28 @@ global_lang="" # Override locale global_disablelang=False alt_path=None +alt_path_dirname=None # Support for setting a local definition file # - Generate the data in a temporary directory named after content hash # - First try alt_path then data_path -def set_local_themedef(file_content: str) -> bool: +def set_local_themedef(file_content: str, overlay: bool=False) -> bool: """ Sets a local theme definition file for the current frontend instance. When set, the FetchDescriptor functions will try the local definition before falling back to global theme data. + - Set overlay=True to overlay on top of existing local definition data (if exists) + WARNING: Pass the file content in str to this function; DO NOT pass the path to the file. This function returns True if successful, otherwise returns False. """ # Determine directory name h=hashlib.shake_256(bytes(file_content, "utf-8")) + global alt_path_dirname dir_name=f"clitheme-data-{h.hexdigest(6)}" # length of 12 (6*2) + if alt_path_dirname!=None and overlay==True: # overlay + dir_name=alt_path_dirname path_name=_globalvar.clitheme_temp_root+"/"+dir_name if global_debugmode: print("[Debug] "+path_name) # Generate data hierarchy as needed @@ -52,6 +58,7 @@ def set_local_themedef(file_content: str) -> bool: return False global alt_path alt_path=path_name+"/"+_globalvar.generator_data_pathname + alt_path_dirname=dir_name return True def unset_local_themedef(): """ @@ -59,6 +66,7 @@ def unset_local_themedef(): After this operation, FetchDescriptor functions will no longer use local definitions. """ global alt_path; alt_path=None + global alt_path_dirname; alt_path_dirname=None class FetchDescriptor(): """ -- Gitee From c3944df47b18b7bbcc870ec138ed7f5464a48e36 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sat, 6 Jan 2024 22:32:51 +0800 Subject: [PATCH 38/58] Update version (20240106) --- debian/changelog | 4 ++-- src/clitheme/_version.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index c0550e0..d6ab192 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ -clitheme (1.1-dev20240101-1) UNRELEASED; urgency=low +clitheme (1.1-dev20240106-1) UNRELEASED; urgency=low * In development, please see commit logs for changes - -- swiftycode <3291929745@qq.com> Mon, 01 Jan 2024 23:39:05 +0800 + -- swiftycode <3291929745@qq.com> Sat, 06 Jan 2024 22:30:00 +0800 clitheme (1.0-r2-1) unstable; urgency=medium diff --git a/src/clitheme/_version.py b/src/clitheme/_version.py index 765f3fc..4ae9c0c 100644 --- a/src/clitheme/_version.py +++ b/src/clitheme/_version.py @@ -1,10 +1,10 @@ # Version definition file; define the package version here # The __version__ variable must be a literal string; DO NOT use variables -__version__="1.1-dev20240101" +__version__="1.1-dev20240106" major=1 minor=1 release=0 # 0 stands for "dev" # For PKGBUILD # version_main CANNOT contain hyphens (-); use underscores (_) instead -version_main="1.1_dev20240101" +version_main="1.1_dev20240106" version_buildnumber=1 \ No newline at end of file -- Gitee From 89416841aa57d1bb8f79083b88de25e9db51e6fb Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Mon, 8 Jan 2024 12:41:06 +0800 Subject: [PATCH 39/58] Support output customization in generator messages --- src/clitheme/_generator.py | 88 +++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/src/clitheme/_generator.py b/src/clitheme/_generator.py index 983d98f..e927ffa 100644 --- a/src/clitheme/_generator.py +++ b/src/clitheme/_generator.py @@ -7,15 +7,19 @@ import random import re try: from . import _globalvar + from . import frontend except ImportError: # for test program import _globalvar + import frontend path="" # to be generated by function +fd=frontend.FetchDescriptor(domain_name="swiftycode", app_name="clitheme", subsections="generator") + def handle_error(message): - raise SyntaxError(message) + raise SyntaxError(fd.feof("error-str", "Syntax error: {msg}", msg=message)) def handle_warning(message): - print("Warning: {}".format(message)) + print(fd.feof("warning-str", "Warning: {msg}", msg=message)) def recursive_mkdir(path, entry_name, line_number_debug): # recursively generate directories (excluding file itself) current_path=path current_entry="" # for error output @@ -23,8 +27,8 @@ def recursive_mkdir(path, entry_name, line_number_debug): # recursively generate current_entry+=x+" " current_path+="/"+x if os.path.isfile(current_path): # conflict with entry file - handle_error("Line {}: cannot create subsection \"{}\" because an entry with the same name already exists"\ - .format(str(line_number_debug), current_entry)) + handle_error(fd.feof("subsection-conflict-err", "Line {num}: cannot create subsection \"{name}\" because an entry with the same name already exists", \ + num=str(line_number_debug), name=current_entry)) elif os.path.isdir(str(current_path))==False: # directory does not exist os.mkdir(current_path) def add_entry(path, entry_name, entry_content, line_number_debug): # add entry to where it belongs (assuming recursive_mkdir already completed) @@ -32,11 +36,11 @@ def add_entry(path, entry_name, entry_content, line_number_debug): # add entry t for x in entry_name.split(): target_path+="/"+x if os.path.isdir(target_path): - handle_error("Line {}: cannot create entry \"{}\" because a subsection with the same name already exists"\ - .format(str(line_number_debug),entry_name)) + handle_error(fd.feof("entry-conflict-err", "Line {num}: cannot create entry \"{name}\" because a subsection with the same name already exists", \ + num=str(line_number_debug), name=entry_name)) elif os.path.isfile(target_path): - handle_warning("Line {}: repeated entry \"{}\", overwriting"\ - .format(str(line_number_debug),entry_name)) + handle_warning(fd.feof("repeated-entry-warn", "Line {num}: repeated entry \"{name}\", overwriting", \ + num=str(line_number_debug), name=entry_name)) f=open(target_path,'w', encoding="utf-8") f.write(entry_content+"\n") def splitarray_to_string(split_content): @@ -49,8 +53,8 @@ def write_infofile(path,filename,content,line_number_debug, header_name_debug): os.makedirs(path) target_path=path+"/"+filename if os.path.isfile(target_path): - handle_warning("Line {}: repeated header info \"{}\", overwriting"\ - .format(str(line_number_debug), header_name_debug)) + handle_warning(fd.feof("repeated-header-warn", "Line {num}: repeated header info \"{name}\", overwriting", \ + num=str(line_number_debug), name=header_name_debug)) f=open(target_path,'w', encoding="utf-8") f.write(content+'\n') @@ -59,8 +63,8 @@ def write_infofile_v2(path: str, filename: str, content_phrases: list[str], line os.makedirs(path) target_path=path+"/"+filename if os.path.isfile(target_path): - handle_warning("Line {}: repeated header info \"{}\", overwriting"\ - .format(str(line_number_debug), header_name_debug)) + handle_warning(fd.feof("repeated-header-warn", "Line {num}: repeated header info \"{name}\", overwriting", \ + num=str(line_number_debug), name=header_name_debug)) f=open(target_path,'w', encoding="utf-8") for line in content_phrases: f.write(line+"\n") @@ -144,7 +148,7 @@ def generate_data_hierarchy(file_content, custom_path_gen=True, custom_infofile_ current_header_entry="" current_header_linenumber=-1 else: # the unlikely case - handle_error("Line {}: internal error while handling block input; please file a bug report".format(str(linenumber))) + handle_error(fd.feof("internal-error-blockinput", "Line {num}: internal error while handling block input; please file a bug report", num=str(linenumber))) # clear data blockinput=False blockinput_data="" @@ -175,22 +179,21 @@ def generate_data_hierarchy(file_content, custom_path_gen=True, custom_infofile_ elif current_status=="": # expect begin_header or begin_main if phrases[0]=="begin_header": if len(phrases)!=1: - handle_error("Extra arguments after \"{}\" on line {}".format(phrases[0],str(linenumber))) + handle_error(fd.feof("extra-arguments-err", "Extra arguments after \"{phrase}\" on line {num}", num=str(linenumber), phrase=phrases[0])) if headerparsed: - handle_error("Repeated header block at line {}".format(str(linenumber))) + handle_error(fd.feof("repeated-header-err", "Repeated header block at line {num}", num=str(linenumber))) current_status="header" elif phrases[0]=="begin_main": if len(phrases)!=1: - handle_error("Extra arguments after \"{}\" on line {}".format(phrases[0],str(linenumber))) + handle_error(fd.feof("extra-arguments-err", "Extra arguments after \"{phrase}\" on line {num}", num=str(linenumber), phrase=phrases[0])) if mainparsed: - handle_error("Repeated main block at line {}".format(str(linenumber))) + handle_error(fd.feof("repeated-main-err", "Repeated main block at line {num}", num=str(linenumber))) current_status="main" - else: handle_error("Unexpected \"{}\" on line {}".format(phrases[0],str(linenumber))) + else: handle_error(fd.feof("invalid-phrase-err", "Unexpected \"{phrase}\" on line {num}", phrase=phrases[0], num=str(linenumber))) elif current_status=="header": # expect name, version, locales, or end_header if phrases[0]=="name" or phrases[0]=="version" or phrases[0]=="description": if len(phrases)<2: - handle_error("Not enough arguments for {} line at line {}"\ - .format(phrases[0],str(linenumber))) + handle_error(fd.feof("not-enough-args-err", "Not enough arguments for \"{phrase}\" at line {num}", phrase=phrases[0], num=str(linenumber))) content=splitarray_to_string(phrases[1:]) write_infofile( \ path+"/"+_globalvar.generator_info_pathname+"/"+custom_infofile_name, \ @@ -198,8 +201,7 @@ def generate_data_hierarchy(file_content, custom_path_gen=True, custom_infofile_ content,linenumber,phrases[0]) # e.g. [...]/theme-info/1/clithemeinfo_name elif phrases[0]=="locales" or phrases[0]=="supported_apps": if len(phrases)<2: - handle_error("Not enough arguments for {} line at line {}"\ - .format(phrases[0],str(linenumber))) + handle_error(fd.feof("not-enough-args-err", "Not enough arguments for \"{phrase}\" at line {num}", phrase=phrases[0], num=str(linenumber))) content=phrases[1:] write_infofile_v2( \ path+"/"+_globalvar.generator_info_pathname+"/"+custom_infofile_name, \ @@ -211,18 +213,17 @@ def generate_data_hierarchy(file_content, custom_path_gen=True, custom_infofile_ blockinput=True # start block input mode elif phrases[0]=="end_header": if len(phrases)!=1: - handle_error("Extra arguments after \"{}\" on line {}".format(phrases[0],str(linenumber))) + handle_error(fd.feof("extra-arguments-err", "Extra arguments after \"{phrase}\" on line {num}", num=str(linenumber), phrase=phrases[0])) current_status="" headerparsed=True - else: handle_error("Unexpected \"{}\" on line {}".format(phrases[0],str(linenumber))) + else: handle_error(fd.feof("invalid-phrase-err", "Unexpected \"{phrase}\" on line {num}", phrase=phrases[0], num=str(linenumber))) elif current_status=="main": # expect entry, in_domainapp, unset_domainapp, end_main if phrases[0]=="entry": if len(phrases)<2: - handle_error("Not enough arguments for {} line at line {}"\ - .format(phrases[0],str(linenumber))) + handle_error(fd.feof("not-enough-args-err", "Not enough arguments for \"{phrase}\" at line {num}", phrase=phrases[0], num=str(linenumber))) # Prevent leading . & prevent /,\ in entry name if _globalvar.sanity_check(splitarray_to_string(phrases[1:]))==False: - handle_error("Line {}: entry subsections/names {}".format(str(linenumber),_globalvar.sanity_check_error_message)) + handle_error(fd.feof("sanity-check-entry-err", "Line {num}: entry subsections/names {sanitycheck_msg}", num=str(linenumber), sanitycheck_msg=_globalvar.sanity_check_error_message)) entry_name=splitarray_to_string(phrases[1:]) # generate entry name if current_subsection!="": entry_name=current_subsection+" "+entry_name if current_domainapp!="": entry_name=current_domainapp+" "+entry_name @@ -230,43 +231,44 @@ def generate_data_hierarchy(file_content, custom_path_gen=True, custom_infofile_ current_status="entry" current_entry_name=entry_name elif phrases[0]=="in_domainapp": - if len(phrases)!=3: - handle_error("Format error in {} at line {}".format(phrases[0],linenumber)) + if len(phrases)<3: + handle_error(fd.feof("not-enough-args-err", "Not enough arguments for \"{phrase}\" at line {num}", phrase=phrases[0], num=str(linenumber))) + elif len(phrases)>3: + handle_error(fd.feof("extra-arguments-err", "Extra arguments after \"{phrase}\" on line {num}", num=str(linenumber), phrase=phrases[0])) # sanity check if _globalvar.sanity_check(phrases[1]+" "+phrases[2])==False: - handle_error("Line {}: domain and app names {}".format(str(linenumber), _globalvar.sanity_check_error_message)) + handle_error(fd.feof("sanity-check-domainapp-err", "Line {num}: domain and app names {sanitycheck_msg}", num=str(linenumber), sanitycheck_msg=_globalvar.sanity_check_error_message)) current_domainapp=phrases[1]+" "+phrases[2] current_subsection="" elif phrases[0]=="in_subsection": if len(phrases)<2: - handle_error("Format error in {} at line {}".format(phrases[0],linenumber)) + handle_error(fd.feof("not-enough-args-err", "Not enough arguments for \"{phrase}\" at line {num}", phrase=phrases[0], num=str(linenumber))) # check if in_domainapp is set if current_domainapp=="": - handle_error("Line {}: in_subsection used before in_domainapp".format(linenumber)) + handle_error(fd.feof("subsection-before-domainapp-err", "Line {num}: in_subsection used before in_domainapp", num=str(linenumber))) # sanity check if _globalvar.sanity_check(splitarray_to_string(phrases[1:]))==False: - handle_error("Line {}: subsection names {}".format(str(linenumber), _globalvar.sanity_check_error_message)) + handle_error(fd.feof("sanity-check-subsection-err", "Line {num}: subsection names {sanitycheck_msg}", num=str(linenumber), sanitycheck_msg=_globalvar.sanity_check_error_message)) current_subsection=splitarray_to_string(phrases[1:]) elif phrases[0]=="unset_domainapp": if len(phrases)!=1: - handle_error("Extra arguments after \"{}\" on line {}".format(phrases[0],str(linenumber))) + handle_error(fd.feof("extra-arguments-err", "Extra arguments after \"{phrase}\" on line {num}", num=str(linenumber), phrase=phrases[0])) current_domainapp="" current_subsection="" elif phrases[0]=="unset_subsection": if len(phrases)!=1: - handle_error("Extra arguments after \"{}\" on line {}".format(phrases[0],str(linenumber))) + handle_error(fd.feof("extra-arguments-err", "Extra arguments after \"{phrase}\" on line {num}", num=str(linenumber), phrase=phrases[0])) current_subsection="" elif phrases[0]=="end_main": if len(phrases)!=1: - handle_error("Extra arguments after \"{}\" on line {}".format(phrases[0],str(linenumber))) + handle_error(fd.feof("extra-arguments-err", "Extra arguments after \"{phrase}\" on line {num}", num=str(linenumber), phrase=phrases[0])) current_status="" mainparsed=True - else: handle_error("Unexpected \"{}\" on line {}".format(phrases[0],str(linenumber))) + else: handle_error(fd.feof("invalid-phrase-err", "Unexpected \"{phrase}\" on line {num}", phrase=phrases[0], num=str(linenumber))) elif current_status=="entry": # expect locale, end_entry if phrases[0]=="locale": if len(phrases)<3: - handle_error("Not enough arguments for {} line at line {}"\ - .format(phrases[0],str(linenumber))) + handle_error(fd.feof("not-enough-args-err", "Not enough arguments for \"{phrase}\" at line {num}", phrase=phrases[0], num=str(linenumber))) content=splitarray_to_string(phrases[2:]) target_entry=current_entry_name if phrases[1]!="default": @@ -274,18 +276,18 @@ def generate_data_hierarchy(file_content, custom_path_gen=True, custom_infofile_ add_entry(datapath,target_entry,content,linenumber) elif phrases[0]=="locale_block": if len(phrases)<2: - handle_error("Format error in {} at line {}".format(phrases[0],linenumber)) + handle_error(fd.feof("not-enough-args-err", "Not enough arguments for \"{phrase}\" at line {num}", phrase=phrases[0], num=str(linenumber))) current_entry_locale=splitarray_to_string(phrases[1:]) current_entry_linenumber=linenumber blockinput=True # start block input elif phrases[0]=="end_entry": if len(phrases)!=1: - handle_error("Extra arguments after \"{}\" on line {}".format(phrases[0],str(linenumber))) + handle_error(fd.feof("extra-arguments-err", "Extra arguments after \"{phrase}\" on line {num}", num=str(linenumber), phrase=phrases[0])) current_status="main" current_entry_name="" - else: handle_error("Unexpected \"{}\" on line {}".format(phrases[0],str(linenumber))) + else: handle_error(fd.feof("invalid-phrase-err", "Unexpected \"{phrase}\" on line {num}", phrase=phrases[0], num=str(linenumber))) if not headerparsed or not mainparsed: - handle_error("Missing or incomplete header or main block") + handle_error(fd.reof("incomplete-block-err", "Missing or incomplete header or main block")) # Update current theme index theme_index=open(path+"/"+_globalvar.generator_info_pathname+"/"+_globalvar.generator_index_filename, 'w', encoding="utf-8") theme_index.write(custom_infofile_name+"\n") -- Gitee From a798546e2540428834edb58ff94ad4ec32004846 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Mon, 8 Jan 2024 18:49:54 +0800 Subject: [PATCH 40/58] Update format of error message output in globalvar --- src/clitheme/_globalvar.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/clitheme/_globalvar.py b/src/clitheme/_globalvar.py index 022ef9c..fa0387c 100644 --- a/src/clitheme/_globalvar.py +++ b/src/clitheme/_globalvar.py @@ -12,6 +12,11 @@ if os.name=="posix": # Linux/macOS only clitheme_root_data_path=os.environ["XDG_DATA_HOME"]+"/clitheme" except KeyError: None +error_msg_str= \ +"""[clitheme] Error: unable to get your home directory or invalid home directory information. +Please make sure that the {var} environment variable is set correctly. +Try restarting your terminal session to fix this issue.""" + if clitheme_root_data_path=="": # prev did not succeed try: if os.name=="nt": # Windows @@ -21,12 +26,10 @@ if clitheme_root_data_path=="": # prev did not succeed raise KeyError clitheme_root_data_path=os.environ["HOME"]+"/.local/share/clitheme" except KeyError: - print("[clitheme] Error: unable to get your home directory or invalid home directory information") + var="$HOME" if os.name=="nt": - print(r"Please make sure that the %USERPROFILE% environment variable is set correctly") - else: - print("Please make sure that the $HOME environment variable is set correctly.") - print("Try restarting your terminal session to fix this issue.") + var=r"%USERPROFILE%" + print(error_msg_str.format(var=var)) exit(1) clitheme_temp_root="/tmp" if os.name=="nt": -- Gitee From 1032b2ecc798c287ec51a9d613e1801f066092a0 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Mon, 8 Jan 2024 20:37:16 +0800 Subject: [PATCH 41/58] Update version (20240108) --- debian/changelog | 4 ++-- src/clitheme/_version.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index d6ab192..9e3ff76 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ -clitheme (1.1-dev20240106-1) UNRELEASED; urgency=low +clitheme (1.1-dev20240108-1) UNRELEASED; urgency=low * In development, please see commit logs for changes - -- swiftycode <3291929745@qq.com> Sat, 06 Jan 2024 22:30:00 +0800 + -- swiftycode <3291929745@qq.com> Mon, 08 Jan 2024 20:30:00 +0800 clitheme (1.0-r2-1) unstable; urgency=medium diff --git a/src/clitheme/_version.py b/src/clitheme/_version.py index 4ae9c0c..741172a 100644 --- a/src/clitheme/_version.py +++ b/src/clitheme/_version.py @@ -1,10 +1,10 @@ # Version definition file; define the package version here # The __version__ variable must be a literal string; DO NOT use variables -__version__="1.1-dev20240106" +__version__="1.1-dev20240108" major=1 minor=1 release=0 # 0 stands for "dev" # For PKGBUILD # version_main CANNOT contain hyphens (-); use underscores (_) instead -version_main="1.1_dev20240106" +version_main="1.1_dev20240108" version_buildnumber=1 \ No newline at end of file -- Gitee From cb566e254f64c83323f0d83131947aea20d46692 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Mon, 8 Jan 2024 20:47:47 +0800 Subject: [PATCH 42/58] Fix frontend import error --- src/clitheme/frontend.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/clitheme/frontend.py b/src/clitheme/frontend.py index 25e9249..13d0a04 100644 --- a/src/clitheme/frontend.py +++ b/src/clitheme/frontend.py @@ -10,10 +10,8 @@ import hashlib from typing import Optional try: from . import _globalvar - from . import _generator except ImportError: # for test program import _globalvar - import _generator data_path=_globalvar.clitheme_root_data_path+"/"+_globalvar.generator_data_pathname global_domain="" @@ -40,6 +38,8 @@ def set_local_themedef(file_content: str, overlay: bool=False) -> bool: This function returns True if successful, otherwise returns False. """ + try: from . import _generator + except ImportError: import _generator # Determine directory name h=hashlib.shake_256(bytes(file_content, "utf-8")) global alt_path_dirname -- Gitee From a08d8066e08cccfffa12b64cb7ad1a1991793a81 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Tue, 9 Jan 2024 22:18:35 +0800 Subject: [PATCH 43/58] Replace "None" with "pass" in except handlers --- src/clitheme/_globalvar.py | 2 +- src/clitheme/cli.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/clitheme/_globalvar.py b/src/clitheme/_globalvar.py index fa0387c..ed95c4e 100644 --- a/src/clitheme/_globalvar.py +++ b/src/clitheme/_globalvar.py @@ -10,7 +10,7 @@ clitheme_root_data_path="" if os.name=="posix": # Linux/macOS only try: clitheme_root_data_path=os.environ["XDG_DATA_HOME"]+"/clitheme" - except KeyError: None + except KeyError: pass error_msg_str= \ """[clitheme] Error: unable to get your home directory or invalid home directory information. diff --git a/src/clitheme/cli.py b/src/clitheme/cli.py index 7b0e919..3ff615a 100755 --- a/src/clitheme/cli.py +++ b/src/clitheme/cli.py @@ -85,7 +85,7 @@ def apply_theme(file_contents: list[str], overlay: bool, preserve_temp=False, ge print(f.reof("applying-theme", "==> Applying theme...")) # remove the current data, ignoring directory not found error try: shutil.rmtree(_globalvar.clitheme_root_data_path) - except FileNotFoundError: None + except FileNotFoundError: pass except Exception: print(f.feof("apply-theme-error", "An error occurred while applying the theme:\n{message}", message=str(sys.exc_info()[1]))) return 1 @@ -98,7 +98,7 @@ def apply_theme(file_contents: list[str], overlay: bool, preserve_temp=False, ge print(f.reof("apply-theme-success", "Theme applied successfully")) if not preserve_temp: try: shutil.rmtree(_generator.path) - except Exception: None + except Exception: pass return 0 def unset_current_theme(): -- Gitee From e1f5553c86e987e2a62c29ee613b41e8f151a866 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Tue, 9 Jan 2024 22:30:19 +0800 Subject: [PATCH 44/58] Add wiki repo information to README --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0de7fcb..004811a 100644 --- a/README.md +++ b/README.md @@ -252,7 +252,9 @@ rm -rf buildtmp srctmp ## 更多信息 - 更多的详细信息和文档请参考本项目Wiki页面:https://gitee.com/swiftycode/clitheme/wikis/pages + - 你也可以通过以下仓库访问这些Wiki页面: + - https://gitee.com/swiftycode/clitheme-wiki-repo + - https://github.com/swiftycode256/clitheme-wiki-repo +- 本仓库中的代码也同步在GitHub上(使用Gitee仓库镜像功能自动同步):https://github.com/swiftycode256/clitheme - 欢迎通过Issues和Pull Requests提交建议和改进。 -- 本仓库中的代码也同步在GitHub上:https://github.com/swiftycode256/clitheme - - GitHub仓库上只包含仓库代码,不包含新版本公告和发行版信息。 - - 不建议在GitHub仓库上提交Issues和Pull Requests,因为我可能不会及时回复。 + - Wiki页面也可以;你可以在上方列出的仓库中提交Issues和Pull Requests \ No newline at end of file -- Gitee From a539830146df15899b68beb34448e8c79551f499 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Tue, 9 Jan 2024 23:35:10 +0800 Subject: [PATCH 45/58] Fix order of local themedef access --- src/clitheme/frontend.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/clitheme/frontend.py b/src/clitheme/frontend.py index 13d0a04..9a77bfc 100644 --- a/src/clitheme/frontend.py +++ b/src/clitheme/frontend.py @@ -182,13 +182,13 @@ class FetchDescriptor(): if path2!=None: path2+="/"+section # path with lang, path with lang but without e.g. .UTF-8, path with no lang possible_paths=[] + for l in lang.split(): + possible_paths.append(path+"__"+l) + possible_paths.append(path) if path2!=None: for l in lang.split(): possible_paths.append(path2+"__"+l) possible_paths.append(path2) - for l in lang.split(): - possible_paths.append(path+"__"+l) - possible_paths.append(path) for p in possible_paths: if self.debug_mode: print("Trying "+p, end="...") try: -- Gitee From cb61fe1b3beffbcf6c0c8a38596cb2b66bc3f1e4 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Tue, 9 Jan 2024 23:36:50 +0800 Subject: [PATCH 46/58] Update version (20240109) --- debian/changelog | 4 ++-- src/clitheme/_version.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index 9e3ff76..be7ba09 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ -clitheme (1.1-dev20240108-1) UNRELEASED; urgency=low +clitheme (1.1-dev20240109-1) UNRELEASED; urgency=low * In development, please see commit logs for changes - -- swiftycode <3291929745@qq.com> Mon, 08 Jan 2024 20:30:00 +0800 + -- swiftycode <3291929745@qq.com> Tue, 09 Jan 2024 23:36:00 +0800 clitheme (1.0-r2-1) unstable; urgency=medium diff --git a/src/clitheme/_version.py b/src/clitheme/_version.py index 741172a..a6d3624 100644 --- a/src/clitheme/_version.py +++ b/src/clitheme/_version.py @@ -1,10 +1,10 @@ # Version definition file; define the package version here # The __version__ variable must be a literal string; DO NOT use variables -__version__="1.1-dev20240108" +__version__="1.1-dev20240109" major=1 minor=1 release=0 # 0 stands for "dev" # For PKGBUILD # version_main CANNOT contain hyphens (-); use underscores (_) instead -version_main="1.1_dev20240108" +version_main="1.1_dev20240109" version_buildnumber=1 \ No newline at end of file -- Gitee From 13de5f3b40f579a66e0a2c3d045a2e3320651164 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Wed, 10 Jan 2024 13:18:01 +0800 Subject: [PATCH 47/58] Fix test program cases --- tests/clithemedef-test_expected.txt | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tests/clithemedef-test_expected.txt b/tests/clithemedef-test_expected.txt index 1b0d7ab..a23da4a 100644 --- a/tests/clithemedef-test_expected.txt +++ b/tests/clithemedef-test_expected.txt @@ -1,12 +1,3 @@ -../theme-info/1/clithemeinfo_locales -en_US zh_CN -../theme-info/1/clithemeinfo_version -1.0 -../theme-info/1/clithemeinfo_name -Example theme -../theme-info/1/clithemeinfo_supported_apps -example-app example-app-two another-example shound_unset-app - com.example/example-app/text-one Some example text one com.example/example-app/text-one__en_US -- Gitee From 13bf3226abc6a6991c1f8582586ada5a344e657c Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sun, 14 Jan 2024 03:39:00 +0800 Subject: [PATCH 48/58] Set utf-8 encoding for test program --- clithemedef-test_testprogram.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clithemedef-test_testprogram.py b/clithemedef-test_testprogram.py index 9fb3f19..fb03f2a 100644 --- a/clithemedef-test_testprogram.py +++ b/clithemedef-test_testprogram.py @@ -5,8 +5,8 @@ import random import string print("Testing generator function...") -mainfile_data=open("tests/clithemedef-test_mainfile.clithemedef.txt",'r').read() -expected_data=open("tests/clithemedef-test_expected.txt",'r').read() +mainfile_data=open("tests/clithemedef-test_mainfile.clithemedef.txt",'r', encoding="utf-8").read() +expected_data=open("tests/clithemedef-test_expected.txt",'r', encoding="utf-8").read() funcresult=_generator.generate_data_hierarchy(mainfile_data) errorcount=0 @@ -21,7 +21,7 @@ for line in expected_data.splitlines(): # read the file contents="" try: - contents=open(rootpath+"/"+current_path).read() + contents=open(rootpath+"/"+current_path, 'r', encoding="utf-8").read() print("File "+rootpath+"/"+current_path+" OK") except FileNotFoundError: print("[File] file "+rootpath+"/"+current_path+" does not exist") @@ -38,7 +38,7 @@ from src.clitheme import frontend frontend.global_lang="en_US.UTF-8" frontend.global_debugmode=True frontend.data_path=_generator.path+"/"+_globalvar.generator_data_pathname -expected_data_frontend=open("tests/clithemedef-test_expected-frontend.txt", 'r').read() +expected_data_frontend=open("tests/clithemedef-test_expected-frontend.txt", 'r', encoding="utf-8").read() current_path_frontend="" errorcount_frontend=0 for line in expected_data_frontend.splitlines(): -- Gitee From 3393fd1c9eb1d606e4adf40832eb3034202cf78c Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Wed, 17 Jan 2024 17:39:59 +0800 Subject: [PATCH 49/58] Support output customization in sanity check --- src/clitheme/_globalvar.py | 26 ++++++++++++++++++++++---- src/clitheme/frontend.py | 8 ++++---- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/clitheme/_globalvar.py b/src/clitheme/_globalvar.py index ed95c4e..e6a5867 100644 --- a/src/clitheme/_globalvar.py +++ b/src/clitheme/_globalvar.py @@ -39,18 +39,36 @@ generator_info_pathname="theme-info" # e.g. ~/.local/share/clitheme/theme-info generator_data_pathname="theme-data" # e.g. ~/.local/share/clitheme/theme-data generator_index_filename="current_theme_index" entry_banphrases=['/','\\'] +startswith_banphrases=['.'] +banphrase_error_message="cannot contain '{char}'" +startswith_error_message="cannot start with '{char}'" # function to check whether the pathname contains invalid phrases # - cannot start with . # - cannot contain banphrases sanity_check_error_message="" + +# retrieve the entry only once to avoid dead loop in frontend.FetchDescriptor callbacks +msg_retrieved=False def sanity_check(path): + # retrieve the entry (only for the first time) + try: from . import frontend + except ImportError: import frontend + global msg_retrieved + if not msg_retrieved: + msg_retrieved=True + f=frontend.FetchDescriptor(domain_name="swiftycode", app_name="clitheme", subsections="sanitycheck") + global banphrase_error_message + banphrase_error_message=f.feof("sanitycheck-banphrase-err", banphrase_error_message, char="{char}") + global startswith_error_message + startswith_error_message=f.feof("sanitycheck-startswith-err", startswith_error_message, char="{char}") global sanity_check_error_message for p in path.split(): - if p.startswith('.'): - sanity_check_error_message="cannot start with '.'" - return False + for b in startswith_banphrases: + if p.startswith(b): + sanity_check_error_message=startswith_error_message.format(char=b) + return False for b in entry_banphrases: if p.find(b)!=-1: - sanity_check_error_message="cannot contain '{}'".format(b) + sanity_check_error_message=banphrase_error_message.format(char=b) return False return True diff --git a/src/clitheme/frontend.py b/src/clitheme/frontend.py index 9a77bfc..d71d176 100644 --- a/src/clitheme/frontend.py +++ b/src/clitheme/frontend.py @@ -126,7 +126,7 @@ class FetchDescriptor(): # Sanity check the path if _globalvar.sanity_check(entry_path)==False: - if self.debug_mode: print("Error: entry names/subsections {}".format(_globalvar.sanity_check_error_message)) + if self.debug_mode: print("[Debug] Error: entry names/subsections {}".format(_globalvar.sanity_check_error_message)) return fallback_string lang="" # Language handling: see https://www.gnu.org/software/gettext/manual/gettext.html#Locale-Environment-Variables for more information @@ -136,7 +136,7 @@ class FetchDescriptor(): if not _globalvar.sanity_check(self.lang)==False: lang=self.lang else: - if self.debug_mode: print("[Debug] Locale: sanity check failed") + if self.debug_mode: print("[Debug] Locale: sanity check failed ({})".format(_globalvar.sanity_check_error_message)) else: if self.debug_mode: print("[Debug] Locale: Using environment variables") # $LANGUAGE (list of languages separated by colons) @@ -162,7 +162,7 @@ class FetchDescriptor(): lang=target_str+" " lang+=re.sub(r"(?P.+)[\.].+", r"\g", target_str) else: - if self.debug_mode: print("[Debug] Locale: sanity check failed") + if self.debug_mode: print("[Debug] Locale: sanity check failed ({})".format(_globalvar.sanity_check_error_message)) # $LANG elif os.environ.__contains__("LANG"): target_str=os.environ["LANG"].strip() @@ -170,7 +170,7 @@ class FetchDescriptor(): lang=target_str+" " lang+=re.sub(r"(?P.+)[\.].+", r"\g", target_str) else: - if self.debug_mode: print("[Debug] Locale: sanity check failed") + if self.debug_mode: print("[Debug] Locale: sanity check failed ({})".format(_globalvar.sanity_check_error_message)) if self.debug_mode: print(f"[Debug] lang: {lang}\n[Debug] entry_path: {entry_path}") # just being lazy here I don't want to check the variables before using ಥ_ಥ (because it doesn't matter) -- Gitee From 1e4fec432d270c7dd86fc1168a8755cf7d85e8e4 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Wed, 17 Jan 2024 20:23:04 +0800 Subject: [PATCH 50/58] Update fallback module/file --- clitheme_fallback.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/clitheme_fallback.py b/clitheme_fallback.py index b21a553..8b94b6b 100644 --- a/clitheme_fallback.py +++ b/clitheme_fallback.py @@ -28,10 +28,13 @@ class FetchDescriptor(): def __init__(self, domain_name: Optional[str] = None, app_name: Optional[str] = None, subsections: Optional[str] = None, lang: Optional[str] = None, debug_mode: Optional[bool] = None, disable_lang: Optional[bool] = None): """Fallback init function""" return - def retrieve_entry_or_Fallback(self, entry_path: str, Fallback_string: str) -> str: + def retrieve_entry_or_Fallback(self, entry_path: str, fallback_string: str) -> str: """Fallback retrieve_entry_or_Fallback function (always return Fallback string)""" - return Fallback_string + return fallback_string reof=retrieve_entry_or_Fallback # a shorter alias of the function + def format_entry_or_fallback(self, entry_path: str, fallback_string: str, *args, **kwargs) -> str: + return fallback_string.format(*args, **kwargs) + feof=format_entry_or_fallback def entry_exists(self, entry_path: str) -> bool: """Fallback entry_exists function (always return false)""" return False \ No newline at end of file -- Gitee From 1b71f4508827cbe545ca587f7a2c11d712c93ace Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Wed, 17 Jan 2024 20:25:34 +0800 Subject: [PATCH 51/58] README: change frontend wording --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 004811a..64d9e6d 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ $ example-app install-file foo-nonexist - 多语言支持 - 支持同时应用多个主题 - 简洁易懂的主题信息文件(`clithemedef`)语法 -- 无需前端API也可访问当前主题数据(易懂的数据结构) +- 无需frontend模块也可访问当前主题数据(易懂的数据结构) `clitheme` 不仅可以定制命令行应用的输出,它还可以: - 为应用程序添加多语言支持 @@ -52,7 +52,7 @@ $ example-app install-file foo-nonexist ### 直接访问主题数据结构 -`clitheme`的核心设计理念之一包括无需使用前端API就可以访问主题数据,并且访问方法直观易懂。这一点在使用其他语言编写的程序中尤其重要,因为前端API目前只提供Python程序的支持。 +`clitheme`的核心设计理念之一包括无需使用frontend模块就可以访问主题数据,并且访问方法直观易懂。这一点在使用其他语言编写的程序中尤其重要,因为frontend模块目前只提供Python程序的支持。 `clitheme`的数据结构采用了**子文件夹**的结构,意味着路径中的每一段代表着数据结构中的一个文件夹/文件。 @@ -64,9 +64,9 @@ $ example-app install-file foo-nonexist ## 前端实施和编写主题文件 -### 使用内置前端API +### 使用内置frontend模块 -使用`clitheme`的python前端API非常简单。只需要新建一个`frontend.FetchDescriptor`实例然后调用该实例中的`retrieve_entry_or_fallback`即可。 +使用`clitheme`的frontend模块非常简单。只需要新建一个`frontend.FetchDescriptor`实例然后调用该实例中的`retrieve_entry_or_fallback`即可。 该函数需要提供路径名称和默认字符串。如果当前主题设定没有适配该字符串,则函数会返回提供的默认字符串。 @@ -96,9 +96,9 @@ filename_err=[...] f.retrieve_entry_or_fallback("file-not-found", "错误:找不到文件 \"{}\"".format(filename_err)) ``` -### 使用前端fallback模块 +### 使用fallback模块 -应用程序还可以在src中内置本项目提供的fallback模块,以便更好的处理`clitheme`模块不存在时的情况。该fallback模块包括了前端API中的所有定义和功能,并且会永远返回失败时的默认值(fallback)。 +应用程序还可以在src中内置本项目提供的fallback模块,以便更好的处理`clitheme`模块不存在时的情况。该fallback模块包括了frontend模块中的所有定义和功能,并且会永远返回失败时的默认值(fallback)。 如需使用,请在你的项目文件中导入`clitheme_fallback.py`文件,并且在你的程序中包括以下代码: -- Gitee From cca7ed734e644163b4da508e34c8a37081aadc01 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Wed, 17 Jan 2024 20:47:11 +0800 Subject: [PATCH 52/58] Update README.md --- README.md | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 64d9e6d..bea038a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # clitheme - 命令行应用文本主题框架 +**中文** | [English](README.en.md) + `clitheme` 允许你定制命令行应用程序的输出,给它们一个你想要的风格和个性。 样例: @@ -56,9 +58,11 @@ $ example-app install-file foo-nonexist `clitheme`的数据结构采用了**子文件夹**的结构,意味着路径中的每一段代表着数据结构中的一个文件夹/文件。 -比如说,`com.example example-app example-text` 的字符串会被存储在`$datapath/com.example/example-app/example-text`。一般情况下,`$datapath`(数据根目录)是 `~/.local/share/clitheme/theme-data`。 +比如说,`com.example example-app example-text` 的字符串会被存储在`/com.example/example-app/example-text`。在Linux和macOS系统下,``是 `$XDG_DATA_HOME/clitheme/theme-data`或`~/.local/share/clitheme/theme-data`。 + +在Windows系统下,``是`%USERPROFILE%\.local\share\clitheme\theme-data`。(`C:\Users\<用户名称>\.local\share\clitheme\theme-data`) -如果需要访问该字符串的其他语言,直接在路径的最后添加`__`加上locale名称就可以了。比如:`$datapath/com.example/example-app/example-text__zh_CN` +如果需要访问该字符串的其他语言,直接在路径的最后添加`__`加上locale名称就可以了。比如:`/com.example/example-app/example-text__zh_CN` 所以说,如果需要直接访问字符串信息,只需要访问对应的文件路径就可以了。 @@ -81,18 +85,18 @@ from clitheme import frontend f=frontend.FetchDescriptor(domain_name="com.example", app_name="example-app") # 对应 “在当前目录找到了2个文件” -fcount=[...] +fcount="[...]" f.retrieve_entry_or_fallback("found-file", "在当前目录找到了{}个文件".format(str(fcount))) # 对应 “-> 正在安装 "example-file"...” -filename=[...] +filename="[...]" f.retrieve_entry_or_fallback("installing-file", "-> 正在安装\"{}\"...".format(filename)) # 对应 “已成功安装2个文件” f.retrieve_entry_or_fallback("install-success", "已成功安装{}个文件".format(str(fcount))) # 对应 “错误:找不到文件 "foo-nonexist"” -filename_err=[...] +filename_err="[...]" f.retrieve_entry_or_fallback("file-not-found", "错误:找不到文件 \"{}\"".format(filename_err)) ``` @@ -109,7 +113,7 @@ except (ModuleNotFoundError, ImportError): import clitheme_fallback as frontend ``` -本项目提供的fallback文件会随版本更新而更改,所以请定期往你的项目里导入最新的fallback文件以获得最新的功能。 +本项目提供的fallback文件会随版本更新而更改,所以请定期往你的项目里导入最新的fallback文件以适配最新的功能。 ### 应用程序应该提供的信息 @@ -132,7 +136,7 @@ com.example example-app file-not-found 错误:找不到文件 "{}" ``` -应用程序还可以在对应的官方文档中包括此信息。如需样例,请参考本仓库中`example-clithemedef`文件夹的README文件。 +应用程序还可以在对应的官方文档中包括此信息。如需样例,请参考本仓库中`example-clithemedef`文件夹的[README文件](example-clithemedef/README.zh-CN.md)。 ### 编写主题文件 @@ -143,6 +147,7 @@ begin_header name 样例主题 version 1.0 locales zh_CN + supported_apps clitheme_demo end_header begin_main @@ -170,7 +175,7 @@ end_main # 安装 -安装`clitheme`非常简单,您可以通过Arch Linux软件包或者pip软件包安装。 +安装`clitheme`非常简单,您可以通过Arch Linux软件包,Debian软件包,或者pip软件包安装。 ### 通过pip软件包安装 @@ -184,7 +189,7 @@ end_main 因为构建的Arch Linux软件包只兼容特定的Python版本,并且升级Python版本后会导致原软件包失效,本项目仅提供构建软件包的方式,不提供构建好的软件包。详细请见下方的**构建Arch Linux软件包**。 -### 通过deb软件包安装 +### 通过Debian软件包安装 因为部分Debian系统(如Ubuntu)上无法使用`pip`往系统里直接安装pip软件包,所以本项目提供Debian软件包。 @@ -208,6 +213,8 @@ end_main $ hatch build +如果这个指令无法正常运行,请尝试运行`hatchling build`。 + 构建完成后,相应的安装包文件可以在当前目录中的`dist`文件夹中找到。 ### 构建Arch Linux软件包 @@ -232,7 +239,7 @@ rm -rf buildtmp srctmp **注意:** 每次升级Python版本时,你需要重新构建并安装软件包,因为软件包只兼容构建时使用的Python版本。 -### 构建deb软件包 +### 构建Debian软件包 因为部分Debian系统(如Ubuntu)上无法使用`pip`往系统里直接安装pip软件包,所以本项目提供Debian软件包。 -- Gitee From fbf6f0e460658f61a8da12e2971aaf801f50ef05 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Wed, 17 Jan 2024 21:48:46 +0800 Subject: [PATCH 53/58] Add English version of README file --- README.en.md | 267 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 README.en.md diff --git a/README.en.md b/README.en.md new file mode 100644 index 0000000..7639254 --- /dev/null +++ b/README.en.md @@ -0,0 +1,267 @@ +# clitheme - A CLI application framework for output customization + +[中文](README.md) | **English** + +`clitheme` allows you to customize the output of command line applications, giving them the style and personality you want. + +Example: +``` +$ example-app install-files +Found 2 files in current directory +-> Installing "example-file"... +-> Installing "example-file-2"... +Successfully installed 2 files +$ example-app install-file foo-nonexist +Error: File "foo-nonexist" not found +``` +``` +$ clitheme apply-theme example-app-theme_clithemedef.txt +==> Generating data... +Successfully generated data +==> Applying theme...Success +Theme applied successfully +``` +``` +$ example-app install-files +o(≧v≦)o Great! Found 2 files in current directory! +(>^ω^<) Installing "example-file"... +(>^ω^<) Installing "example-file-2:"... +o(≧v≦)o Successfully installed 2 files! +$ example-app install-file foo-nonexist +ಥ_ಥ Oh no, something went wrong! File "foo-nonexist" not found +``` + +## Features + +- Multi-language (Internationalization) support +- Supports applying multiple themes simultaneously +- Clear and easy-to-understand theme definition file (`clithemedef`) syntax +- The theme data can be easily accessed without the use of frontend module + +Not only `clitheme` can customize the output of command-line applications, it can also: +- Add support for another language for an application +- Support GUI applications + +# Basic usage + +## Data hierarchy and path naming + +Applications use **path names** to specify the string definitions they want. Subsections in the path name is separated using spaces. The first two subsections are usually reserved for the developer and application name. Theme definition files will use this path name to adopt corresponding string definitions, achieving the effect of output customization. + +For example, the path name `com.example example-app example-text` refers to the `example-text` string definition for the `example-app` application developed by `com.example`. + +It is not required to always follow this path naming convention and specifying global definitions (not related to any specific application) is allowed. For example, `global-entry` and `global-example global-text` are also valid path names. + +### Directly accessing the theme data hierarchy + +One of the key design principles of `clitheme` is that the use of frontend module is not needed to access the theme data hierarchy, and its method is easy to understand and implement. This is important especially in applications written in languages other than Python because Python is the only language supported by the frontend module. + +The data hierarchy is organized in a **subfolder structure**, meaning that every subsection in the path name represent a file or folder in the data hierarchy. + +For example, the contents of string definition `com.example example-app example-text` is stored in the directory `/com.example/example-app`. `` is `$XDG_DATA_HOME/clitheme/theme-data` or `~/.local/share/clitheme/theme-data` under Linux and macOS systems. + +Under Windows systems, `` is `%USERPROFILE%\.local\share\clitheme\theme-data` or `C:\Users\\.local\share\clitheme\theme-data`. + +To access a specific language of a string definition, add `__` plus the locale name to the end of the directory path. For example: `/com.example/example-app/example-text__en_US` + +In conclusion, to directly access a specific string definition, convert the path name to a directory path and access the file located there. + +## Frontend implementation and writing theme definition files + +### Using the built-in frontend module + +Using the frontend module provided by `clitheme` is very easy and straightforward. To access a string definition in the current theme setting, create a new `frontend.FetchDescriptor` object and use the provided `retrieve_entry_or_fallback` function. + +You need to pass the path name and a fallback string to this function. If the current theme setting does not provide the specified path name and string definition, the function will return the fallback string. + +You can pass the `domain_name`, `app_name`, and `subsections` arguments when creating a new `frontend.FetchDescriptor` object. When specified, these arguments will be automatically appended in front of the path name provided when calling the `retrieve_entry_or_fallback` function. + +Let's demonstrate it using the previous examples: + +```py +from clitheme import frontend + +# Create a new FetchDescriptor object +f=frontend.FetchDescriptor(domain_name="com.example", app_name="example-app") + +# Corresponds to "Found 2 files in current directory" +fcount="[...]" +f.retrieve_entry_or_fallback("found-file", "在当前目录找到了{}个文件".format(str(fcount))) + +# Corresponds to "-> Installing "example-file"..." +filename="[...]" +f.retrieve_entry_or_fallback("installing-file", "-> 正在安装\"{}\"...".format(filename)) + +# Corresponds to "Successfully installed 2 files" +f.retrieve_entry_or_fallback("install-success", "已成功安装{}个文件".format(str(fcount))) + +# Corresponds to "Error: File "foo-nonexist" not found" +filename_err="[...]" +f.retrieve_entry_or_fallback("file-not-found", "错误:找不到文件 \"{}\"".format(filename_err)) +``` + +### Using the fallback frontend module + +You can integrate the fallback frontend module provided by this project to better handle situations when `clitheme` does not exist on the system. This fallback module contains all the functions in the frontend module, and its functions will always return fallback values. + +Import the `clitheme_fallback.py` file from the repository and insert the following code in your project to use it: + +```py +try: + from clitheme import frontend +except (ModuleNotFoundError, ImportError): + import clitheme_fallback as frontend +``` + +The fallback module provided by this project will update accordingly with new versions. Therefore, it is recommended to import the latest version of this module to adopt the latest features. + +### Information your application should provide + +To allow users to write theme definition files of your application, your application should provide information about supported string definitions with its path name and default string. + +For example, your app can implement a feature to output all supported string definitions: + +``` +$ example-app --clitheme-output-defs +com.example example-app found-file +Found {} files in current directory + +com.example example-app installing-file +-> Installing "{}"... + +com.example example-app install-success +Successfully installed {} files + +com.example example-app file-not-found +Error: file "{}" not found +``` + +You can also include this information in your project's official documentation. The demo application in this repository provides an example of it and the corresponding README file is located in the folder `example-clithemedef`. + +### Writing theme definition files + +Consult the Wiki pages and documentation for detailed syntax of theme definition files. An example is provided below: + +``` +begin_header + name Example theme + version 1.0 + locales en_US + supported_apps clitheme_demo +end_header + +begin_main + in_domainapp com.example example-app + entry found-file + locale default o(≧v≦)o Great! Found {} files in current directory! + locale en_US o(≧v≦)o Great! Found {} files in current directory! + end_entry + entry installing-file + locale default (>^ω^<) Installing "{}"... + locale en_US (>^ω^<) Installing "{}"... + end_entry + entry install-success + locale default o(≧v≦)o Successfully installed {} files! + locale en_US o(≧v≦)o Successfully installed {} files! + end_entry + entry file-not-found + locale default ಥ_ಥ Oh no, something went wrong! File "foo-nonexist" not found + locale en_US ಥ_ಥ Oh no, something went wrong! File "foo-nonexist" not found + end_entry +end_main +``` + +Use the command `clitheme apply-theme ` to apply the theme definition file onto the system. Supported applications will start using the string definitions listed in this file. + +# Installation + +Installing `clitheme` is very easy. You can use the provided Arch Linux, Debian, or pip package to install it. + +### Install using pip + +Download the whl file from the latest release and install it using `pip`: + + $ pip install clitheme--py3-none-any.whl + +### Install using Arch Linux package + +Because `pip` cannot be used to install Python packages onto an Arch Linux system, this project provides an Arch Linux package. + +Because the built package only supports a specific Python version and will stop working when Python is upgraded, this project only provides files needed to build the package. Please see **Build Arch Linux package** for more information. + +### Install using Debian package + +Because `pip` cannot be used to install Python packages onto certain Debian Linux distributions, this project provides a Debian package. + +Download the `.deb` file from the latest release and install it using `apt`: + + $ sudo apt install ./clitheme__all.deb + +## Building the installation package + +You can also build the installation package from source code, which allows you to include the latest or custom changes. This is the only method to install the latest development version of `clitheme`. + +### Build pip package + +`clitheme` uses the `hatchling` build backend, so installing it is required for building the package. + +First, install the `hatch` package. You can use the software package provided by your Linux distribution, or install it using `pip`: + + $ pip install hatch + +Next, making sure that you are under the project directory, use `hatch build` to build the package: + + $ hatch build + +If this command does not work, try using `hatchling build` instead. + +The corresponding pip package (whl file) can be found in the `dist` folder under the working directory. + +### Build Arch Linux package + +Make sure that the `base-devel` package is installed before building the package. You can install it using the following command: + + $ sudo pacman -S base-devel + +To build the package, run `makepkg` under the project directory. You can use the following commands: + +```sh +# Delete the temporary directories if makepkg has been run before. Issues will occur if you do not do so. +rm -rf buildtmp srctmp + +makepkg -si +# -s: install dependencies required for building the package +# -i: automatically install the built package + +# You can remove the temporary directories after you are finished +rm -rf buildtmp srctmp +``` + +**Warning:** You must rebuild the package every time Python is upgraded, because the package only works under the Python version when the package is built. + +### Build Debian package + +Because `pip` cannot be used to install Python packages onto certain Debian Linux distributions, this project provides a Debian package. + +The following packages are required prior to building the package: + +- `debhelper` +- `dh-python` +- `python3-hatchling` +- `dpkg-dev` + +They can be installed using this command: + + sudo apt install debhelper dh-python python3-hatchling dpkg-dev + +Run `dpkg-buildpackage -b` to build the package. A `.deb` file will be generated in the upper folder after the build process finishes. + +## More information + +- For more information, please reference the project's Wiki pages: https://gitee.com/swiftycode/clitheme/wikis/pages + - You can also access the pages in these repositories: + - https://gitee.com/swiftycode/clitheme-wiki-repo + - https://github.com/swiftycode256/clitheme-wiki-repo +- This repository is also synced onto GitHub (using Gitee automatic sync feature): https://github.com/swiftycode256/clitheme +- You are welcome to propose suggestions and changes using Issues and Pull Requests + - Use the Wiki repositories listed above for Wiki-related suggestions \ No newline at end of file -- Gitee From 7137a70021e3f277b646de07b12f72651d1b0640 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Wed, 17 Jan 2024 21:49:45 +0800 Subject: [PATCH 54/58] Update version (1.1-dev20240117) --- debian/changelog | 4 ++-- src/clitheme/_version.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index be7ba09..e1196f2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ -clitheme (1.1-dev20240109-1) UNRELEASED; urgency=low +clitheme (1.1-dev20240117-1) UNRELEASED; urgency=low * In development, please see commit logs for changes - -- swiftycode <3291929745@qq.com> Tue, 09 Jan 2024 23:36:00 +0800 + -- swiftycode <3291929745@qq.com> Wed, 17 Jan 2024 21:50:00 +0800 clitheme (1.0-r2-1) unstable; urgency=medium diff --git a/src/clitheme/_version.py b/src/clitheme/_version.py index a6d3624..5f093d9 100644 --- a/src/clitheme/_version.py +++ b/src/clitheme/_version.py @@ -1,10 +1,10 @@ # Version definition file; define the package version here # The __version__ variable must be a literal string; DO NOT use variables -__version__="1.1-dev20240109" +__version__="1.1-dev20240117" major=1 minor=1 release=0 # 0 stands for "dev" # For PKGBUILD # version_main CANNOT contain hyphens (-); use underscores (_) instead -version_main="1.1_dev20240109" +version_main="1.1_dev20240117" version_buildnumber=1 \ No newline at end of file -- Gitee From 8b21d193299a8fc2031fce23a3a47f72ef5bc6a8 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Wed, 17 Jan 2024 22:25:32 +0800 Subject: [PATCH 55/58] Update version (1.1-r1) --- debian/changelog | 8 +++++--- src/clitheme/_version.py | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/debian/changelog b/debian/changelog index e1196f2..37f8e4c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,10 @@ -clitheme (1.1-dev20240117-1) UNRELEASED; urgency=low +clitheme (1.1-r1-1) unstable; urgency=medium - * In development, please see commit logs for changes + * Version 1.1-r1 in Debian package format + For more information please see: + https://gitee.com/swiftycode/clitheme/releases/tag/v1.1-r1 - -- swiftycode <3291929745@qq.com> Wed, 17 Jan 2024 21:50:00 +0800 + -- swiftycode <3291929745@qq.com> Wed, 17 Jan 2024 22:14:00 +0800 clitheme (1.0-r2-1) unstable; urgency=medium diff --git a/src/clitheme/_version.py b/src/clitheme/_version.py index 5f093d9..2c71ced 100644 --- a/src/clitheme/_version.py +++ b/src/clitheme/_version.py @@ -1,10 +1,10 @@ # Version definition file; define the package version here # The __version__ variable must be a literal string; DO NOT use variables -__version__="1.1-dev20240117" +__version__="1.1-r1" major=1 minor=1 -release=0 # 0 stands for "dev" +release=1 # 0 stands for "dev" # For PKGBUILD # version_main CANNOT contain hyphens (-); use underscores (_) instead -version_main="1.1_dev20240117" +version_main="1.1_r1" version_buildnumber=1 \ No newline at end of file -- Gitee From 870a51ebe99ad885436f1627fdd0c1c39bdf5cbb Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sat, 20 Jan 2024 13:59:50 +0800 Subject: [PATCH 56/58] Fix some string definition references --- src/clitheme/cli.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/clitheme/cli.py b/src/clitheme/cli.py index 3ff615a..b9abdc5 100755 --- a/src/clitheme/cli.py +++ b/src/clitheme/cli.py @@ -165,20 +165,20 @@ def get_current_theme_info(): print(f.feof("list-item", "• {content}", content=locale.strip())) elif os.path.isfile(target_path+"/"+"clithemeinfo_locales"): locales=open(target_path+"/"+"clithemeinfo_locales", 'r', encoding="utf-8").read().strip() - print("Supported locales: ") + print(f.reof("locales-str", "Supported locales:")) for locale in locales.split(): print(f.feof("list-item", "• {content}", content=locale.strip())) # supported_apps supported_apps="(Unknown)" if os.path.isfile(target_path+"/"+"clithemeinfo_supported_apps_v2"): supported_apps=open(target_path+"/"+"clithemeinfo_supported_apps_v2", 'r', encoding="utf-8").read().strip() - print("Supported apps: ") + print(f.reof("supported-apps-str", "Supported apps:")) for app in supported_apps.splitlines(): if app.strip()!="": print(f.feof("list-item", "• {content}", content=app.strip())) elif os.path.isfile(target_path+"/"+"clithemeinfo_supported_apps"): supported_apps=open(target_path+"/"+"clithemeinfo_supported_apps", 'r', encoding="utf-8").read().strip() - print("Supported apps: ") + print(f.reof("supported-apps-str", "Supported apps:")) for app in supported_apps.split(): print(f.feof("list-item", "• {content}", content=app.strip())) return 0 -- Gitee From 8d69069371a6ef45c56e6a9b7314bff506868af1 Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sat, 20 Jan 2024 15:44:02 +0800 Subject: [PATCH 57/58] Change path names for sanity check function --- src/clitheme/_globalvar.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/clitheme/_globalvar.py b/src/clitheme/_globalvar.py index e6a5867..8bcc48e 100644 --- a/src/clitheme/_globalvar.py +++ b/src/clitheme/_globalvar.py @@ -56,11 +56,11 @@ def sanity_check(path): global msg_retrieved if not msg_retrieved: msg_retrieved=True - f=frontend.FetchDescriptor(domain_name="swiftycode", app_name="clitheme", subsections="sanitycheck") + f=frontend.FetchDescriptor(domain_name="swiftycode", app_name="clitheme", subsections="generator") global banphrase_error_message - banphrase_error_message=f.feof("sanitycheck-banphrase-err", banphrase_error_message, char="{char}") + banphrase_error_message=f.feof("sanity-check-msg-banphrase-err", banphrase_error_message, char="{char}") global startswith_error_message - startswith_error_message=f.feof("sanitycheck-startswith-err", startswith_error_message, char="{char}") + startswith_error_message=f.feof("sanity-check-msg-startswith-err", startswith_error_message, char="{char}") global sanity_check_error_message for p in path.split(): for b in startswith_banphrases: -- Gitee From 262adc853bbc9d4c81b3c20dae126d3dec716eae Mon Sep 17 00:00:00 2001 From: swiftycode <10752639+swiftycode@user.noreply.gitee.com> Date: Sat, 20 Jan 2024 15:52:08 +0800 Subject: [PATCH 58/58] Change date on mandoc --- docs/clitheme.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/clitheme.1 b/docs/clitheme.1 index b48338e..d9614b2 100644 --- a/docs/clitheme.1 +++ b/docs/clitheme.1 @@ -1,4 +1,4 @@ -.TH clitheme 1 2023-12-16 +.TH clitheme 1 2024-01-20 .SH NAME clitheme \- frontend to customize output of applications .SH SYNOPSIS -- Gitee