From ae65b21b923292f8d56b563e1af4a79a32a259a9 Mon Sep 17 00:00:00 2001 From: sudoskys Date: Wed, 7 Feb 2024 18:45:16 +0800 Subject: [PATCH 1/3] :sparkles: feat(server): Add user login endpoint Added a new endpoint for user login in the server.py file. The login endpoint allows users to log in and returns the result. If any error occurs during the login process, an exception is logged and a 500 status code is returned. The new endpoint is defined as a POST request at `/user/login`. The request body expects a `Login` object. --- playground/random_prompt.py | 13 + .../utils/random_prompt/__init__.py | 109 +++++-- src/novelai_python/utils/random_prompt/tag.py | 27 +- .../utils/random_prompt/tag_artist.py | 22 +- .../utils/random_prompt/tag_character.py | 270 ++++++++++++++++++ .../utils/random_prompt/tag_nsfw.py | 16 ++ 6 files changed, 421 insertions(+), 36 deletions(-) create mode 100644 playground/random_prompt.py create mode 100644 src/novelai_python/utils/random_prompt/tag_character.py diff --git a/playground/random_prompt.py b/playground/random_prompt.py new file mode 100644 index 0000000..fe27cbc --- /dev/null +++ b/playground/random_prompt.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# @Time : 2024/2/7 下午12:51 +# @Author : sudoskys +# @File : random_prompt.py +# @Software: PyCharm +import random + +from novelai_python.utils.random_prompt import RandomPromptGenerator + + +print(random.random()) +s = RandomPromptGenerator(nsfw_enabled=True).generate() +print(s) diff --git a/src/novelai_python/utils/random_prompt/__init__.py b/src/novelai_python/utils/random_prompt/__init__.py index b9306d4..dbd63b3 100644 --- a/src/novelai_python/utils/random_prompt/__init__.py +++ b/src/novelai_python/utils/random_prompt/__init__.py @@ -14,6 +14,7 @@ action, expression, footwears, bottoms, color as colors ) from .tag_artist import rankArtist +from .tag_character import rankMoods, rankCharacter, rankIdentity from .tag_nsfw import nsfw @@ -33,7 +34,7 @@ def get_weighted_choice(tags, existing_tags: List[str]): len(tag) < 3 or not tag[2] or any(sub_tag in existing_tags for sub_tag in tag[2])] total_weight = sum(tagr[1] for tagr in valid_tags if len(tagr) > 1) if total_weight == 0: - return '' + return random.choice(tags) random_number = random.randint(1, total_weight) cumulative_weight = 0 for tag in valid_tags: @@ -42,9 +43,10 @@ def get_weighted_choice(tags, existing_tags: List[str]): return tag[0] raise ValueError('get_weighted_choice: should not reach here') - def character_features(self, gender, camera_angle, nsfw_enabled, num_characters): + def character_features(self, gender, camera_angle, nsfw_enabled, num_characters, enable_skin_color=True): """ Add character features to the prompt + :param enable_skin_color: enable skin :param gender: 'm', 'f', 'o' :param camera_angle: the camera angle of the prompt :param nsfw_enabled: True or False @@ -57,26 +59,26 @@ def character_features(self, gender, camera_angle, nsfw_enabled, num_characters) features.append(self.get_weighted_choice(animalFeatures, features)) unique_features = {'mermaid', 'centaur', 'lamia'} has_unique_feature = any(feature in features for feature in unique_features) - if random.random() < 0.1: + if random.random() < 0.1 and enable_skin_color: features.append(self.get_weighted_choice(sinkColor, features)) - if random.random() < 0.8: + if random.random() < 0.3: features.append(self.get_weighted_choice(eyeColors, features)) if random.random() < 0.1: features.append(self.get_weighted_choice(eyeCharacteristics, features)) - if random.random() < 0.7: + if random.random() < 0.6: features.append(self.get_weighted_choice(eyesExpression, features)) - if random.random() < 0.8: + if random.random() < 0.2: features.append(self.get_weighted_choice(hairLength, features)) - if random.random() < 0.5: + if random.random() < 0.2: features.append(self.get_weighted_choice(backHairStyle, features)) - if random.random() < 0.5: + if random.random() < 0.2: features.append(self.get_weighted_choice(hairColors, features)) if random.random() < 0.1: features.append(self.get_weighted_choice(hairColorExtra, features)) features.append(self.get_weighted_choice(hairColors, features)) if random.random() < 0.1: features.append(self.get_weighted_choice(hairFeatures, features)) - if gender.startswith('f') and random.random() < 0.6: + if gender.startswith('f') and random.random() < 0.8: features.append(self.get_weighted_choice(breastsSize, features)) num_body_features = 0 if num_characters == 1: @@ -87,9 +89,9 @@ def character_features(self, gender, camera_angle, nsfw_enabled, num_characters) num_body_features = self.get_weighted_choice([[0, 30], [1, 30]], features) for _ in range(num_body_features): features.append(self.get_weighted_choice(bodyFeatures, features)) - if random.random() < 0.5: + if random.random() < 0.3: features.append(self.get_weighted_choice(headWears, features)) - if random.random() < 0.4: + if random.random() < 0.5: features.append(self.get_weighted_choice(hatOrnaments, features)) clothing_type = self.get_weighted_choice(['uniform', 'swimsuit', 'bodysuit', 'normal clothes'], features) if nsfw_enabled and random.random() < 0.9: @@ -101,7 +103,7 @@ def character_features(self, gender, camera_angle, nsfw_enabled, num_characters) features.append(underwear_choice) if random.random() < 0.5: clothing_type = None - if random.random() < 0.4: + if random.random() < 0.5: features.append(self.get_weighted_choice(nsfw["naked"], features)) clothing_type = None if clothing_type == 'uniform': @@ -130,17 +132,24 @@ def character_features(self, gender, camera_angle, nsfw_enabled, num_characters) features.append(f'{color} {footwear}') if random.random() < 0.7: features.append(self.get_weighted_choice(expression, features)) - if random.random() < (1 if nsfw_enabled and num_characters == 1 else 0.5): + if random.random() < (1 if nsfw_enabled and num_characters >= 1 else 0.5): + # 单角色 + nsfw 为 1 possible_actions = action if nsfw_enabled: + if random.random() < 0.3: + features.append(self.get_weighted_choice(nsfw["action"], features)) + if random.random() < 0.25: + features.append(self.get_weighted_choice(nsfw["pussyForeplay"], features)) possible_actions += nsfw["action"] + nsfw["analForeplay"] + nsfw["pussyForeplay"] if random.random() < 0.5: possible_actions += nsfw["footForeplay"] features.append(self.get_weighted_choice(possible_actions, features)) + # 睡眠 if any('sleeping' in feature for feature in features) \ or any('zzz' in feature for feature in features) \ or any('closed eyes' in feature for feature in features): features = [feature for feature in features if not any(color[0] == feature for color in eyeColors)] + # 衣物 num_clothing_accessories = 0 if num_characters == 1: num_clothing_accessories = self.get_weighted_choice([[0, 10], [1, 30], [2, 15], [3, 5]], features) @@ -155,10 +164,33 @@ def character_features(self, gender, camera_angle, nsfw_enabled, num_characters) features = [feature for feature in features if 'legwear' not in feature] return features - def generate(self): - return self.random_prompt() + def generate(self, + *, + enable_moods: bool = True, + enable_character: bool = True, + enable_identity: bool = True, + ): + """ + Generate a random prompt + :param enable_moods: enable moods + :param enable_character: enable character + :param enable_identity: enable identity + :return: + """ + return self.random_prompt( + enable_moods=enable_moods, + enable_character=enable_character, + enable_identity=enable_identity + ) - def random_prompt(self): + def random_prompt(self, *, + man_w: int = 30, + woman_w: int = 60, + other_w: int = 10, + enable_moods: bool = True, + enable_character: bool = True, + enable_identity: bool = False, + ): tags = [] if self.nsfw_enabled: tags.append('nsfw') @@ -184,15 +216,17 @@ def random_prompt(self): return ', '.join(tags) if random.random() < 0.3: tags.append(self.get_weighted_choice(artStyle, tags)) - if random.random() < 0.55: + if random.random() < 0.5: tags.append("{" + self.get_weighted_choice(rankArtist, tags) + "}") - if random.random() < 0.3: - tags.append(self.get_weighted_choice(rankArtist, tags)) + if random.random() < 0.5: + tags.append("[" + self.get_weighted_choice(rankArtist, tags) + "]") + if random.random() < 0.5: + tags.append("{{" + self.get_weighted_choice(rankArtist, tags) + "}}") c_count = 0 d_count = 0 u_count = 0 for _ in range(irs): - random_gender = self.get_weighted_choice([['m', 30], ['f', 50], ['o', 10]], tags) + random_gender = self.get_weighted_choice([['m', man_w], ['f', woman_w], ['o', other_w]], tags) if random_gender == 'm': d_count += 1 elif random_gender == 'f': @@ -218,33 +252,48 @@ def random_prompt(self): elif u_count == 3: tags.insert(0, '3others') if self.nsfw_enabled: - g_count = c_count + u_count if c_count >= 2 and d_count == 0 and random.random() < 0.7 else 0 + g_count = c_count + u_count + if (c_count >= 2 and d_count == 0) and random.random() < 0.7: + # 2girls + tags.append(self.get_weighted_choice(nsfw["yu"], tags)) if g_count == 0 and d_count >= 2 and c_count == 0: tags.append(nsfw["ya"]) if d_count > 0: - if random.random() < 0.4: - tags.append(self.get_weighted_choice(nsfw["penis"], tags)) + if c_count > 0: + if random.random() < 0.6: + tags.append(self.get_weighted_choice(nsfw["penis"], tags)) + else: + if random.random() < 0.3: + tags.append(self.get_weighted_choice(nsfw["penis"], tags)) if d_count > 0 and g_count > 0: if random.random() < 0.5: tags.append(self.get_weighted_choice(nsfw["analSex"], tags)) if g_count > 0: - if random.random() < 0.6: + features = [] + if random.random() < 0.3: features = self.character_features(nsfw['fu'], None, True, irs) - else: - features = self.character_features(nsfw['yu'], None, True, irs) - if random.random() < 0.2: + if random.random() < 0.6: tags.append(self.get_weighted_choice(nsfw["sex"], tags)) - if random.random() < 0.2: + if random.random() < 0.6: tags.append(self.get_weighted_choice(nsfw["pussy"], tags)) if random.random() < 0.6: tags.append(self.get_weighted_choice(nsfw["sexMod"], tags)) if random.random() < 0.6: tags.append(self.get_weighted_choice(nsfw["sexActionMode"], tags)) - if random.random() < 0.1: + if random.random() < 0.2: tags.append(self.get_weighted_choice(nsfw["bdsm"], tags)) - if random.random() < 0.1: + if random.random() < 0.3: tags.append(self.get_weighted_choice(nsfw["sexAccessories"], tags)) tags.extend(features) + if random.random() < 0.65 and enable_moods: + # 心情 + tags.append("[" + self.get_weighted_choice(rankMoods, tags) + "]") + if random.random() < 0.5 and enable_identity: + # 身份 + tags.append("[" + self.get_weighted_choice(rankIdentity, tags) + "]") + if random.random() < 0.2 and enable_character: + # 角色 + tags.append("[" + self.get_weighted_choice(rankCharacter, tags) + "]") if random.random() < 0.1: bg_color = self.get_weighted_choice(backgroundColor, tags) tags.append(bg_color) diff --git a/src/novelai_python/utils/random_prompt/tag.py b/src/novelai_python/utils/random_prompt/tag.py index d828036..f1d93fd 100644 --- a/src/novelai_python/utils/random_prompt/tag.py +++ b/src/novelai_python/utils/random_prompt/tag.py @@ -1334,7 +1334,7 @@ ], [ 'jester cap', - 5 + 1 ], [ 'frilled hat', @@ -7425,15 +7425,16 @@ ] hairColorExtra = [ - ['multicolored hair', - 5], + [ + 'multicolored hair', + 5], [ 'colored inner hair', 5 ], [ 'gradient hair', - 5 + 10 ], [ 'rainbow hair', @@ -7521,3 +7522,21 @@ 1 ] ] + +if __name__ == "__main__": + var = vars().copy() + + # 获取tags列表 + tags = [] + for key, value in var.items(): + if not key.startswith('_') and key != 'var': + tags.extend(value) + print(tags) + + # 展开二级列表 + tags = [tag[0] for tag in tags] + print(tags) + import json + + with open('../../../../playground/cos/tags.json', 'w') as f: + json.dump(tags, f) diff --git a/src/novelai_python/utils/random_prompt/tag_artist.py b/src/novelai_python/utils/random_prompt/tag_artist.py index 31dfb27..bc3dde9 100644 --- a/src/novelai_python/utils/random_prompt/tag_artist.py +++ b/src/novelai_python/utils/random_prompt/tag_artist.py @@ -376,5 +376,23 @@ [ "mamimi_(mamamimi)", 100 - ] -] \ No newline at end of file + ], +] + +if __name__ == "__main__": + var = vars().copy() + + # 获取tags列表 + tags = [] + for key, value in var.items(): + if not key.startswith('_') and key != 'var': + tags.extend(value) + print(tags) + + # 展开二级列表 + tags = [tag[0] for tag in tags] + print(tags) + import json + + with open('../../../../playground/cos/tag_artist.json', 'w') as f: + json.dump(tags, f) \ No newline at end of file diff --git a/src/novelai_python/utils/random_prompt/tag_character.py b/src/novelai_python/utils/random_prompt/tag_character.py new file mode 100644 index 0000000..56dd0d8 --- /dev/null +++ b/src/novelai_python/utils/random_prompt/tag_character.py @@ -0,0 +1,270 @@ +# -*- coding: utf-8 -*- +# @Time : 2024/2/7 下午5:56 +# @Author : sudoskys +# @File : tag_character.py +# @Software: PyCharm + +rankCharacter = [ + ['futanari-sama_(mdf_an)', 10], + ['kouhai-chan_(mignon)', 10], + ['kaleina_(ricegnat)', 10], + ['sarah-san_(mignon)', 10], + ['shiro-chan_(mignon)', 10], + ['ichigo-chan_(mignon)', 10], + ['hiyake-chan', 10], + ['pandora_acherona_(nat_the_lich)', 10], + ['nil_sunna', 10], + ['brown_twintails_girl_(mdf_an)', 10], + ['blonde_ponytail_girl_(mdf_an)', 10], + ['tsona_(nyantcha)', 10], + ['meruccubus_(merunyaa)', 10], ['saki_(the_atko)', 10], ['ophelia_(bigrbear)', 10], + ['chariot_(black_rock_shooter)', 10], ['hoshizuki_suzu', 10], ['hoshizuki_kaede', 10], + ['chloe_(sciamano240)', 10], ['asutora-chan', 10], ['sunomiya_sana', 10], + ['aibo_(gorgeous_mushroom)', 10], ['hachiouji_naoto', 10], ['gojou_wakana', 10], + ['tokisaki_asaba', 10], ['guild_girl_(goblin_slayer!)', 10], ['chobi_(akchu)', 10], + ['kurohanya_(niliu_chahui)', 10], ['yoshi_(nagatoro)', 10], ['oosuki_mamako', 10], + ['riley_fairfeather', 10], ['olga_discordia', 10], ['lillia_greyrat', 10], ['thai_girl_(okpriko)', 10], + ['uzaki_tsuki', 10], ['inui_sajuna', 10], ['okuzumi_yuiko', 10], ['tokisaki_mio', 10], + ['shione_(niliu_chahui)', 10], ['sapphira_nyx', 10], ['cerestia_of_life', 10], + ['celestine_lucullus', 10], ['angelise_reiter', 10], ['south_dakota_(solo_concert)_(azur_lane)', 10], + ['anubis_(houtengeki)', 10], ['nanami_mizuki', 10], + ['regensburg_(dark_dragon_brilliant_beach)_(azur_lane)', 10], ['ursula_(takunomi)', 10], + ['blonde_girl_(okpriko)', 10], ['paldea_mother', 10], ['gamou_maki', 10], ['aegis_(takunomi)', 10], + ['uketsuke_succubus_(konosuba)', 10], ['ursula_(23)', 10], + ['aegir_(golden_dragon_among_auspicious_clouds)_(azur_lane)', 10], ['tiona_hyryute', 10], + ['priana', 10], ['shinano_(moonlit_chrome)_(azur_lane)', 10], ['volume_(nikke)', 10], + ['tione_hyryute', 10], ['hinano_(sky-freedom)', 10], ['noumu_(boku_no_hero_academia)', 10], + ['st._louis_(luxurious_wheels)_(azur_lane)', 10], ['iwami_sayaka', 10], + ['hilichurl_(genshin_impact)', 10], ['kali_belladonna', 10], ['nagatoro_hayase', 10], + ['yui_(sky-freedom)', 10], ['new_jersey_(midsummer_leisure)_(azur_lane)', 10], + ['yorktown_ii_(bright-sky_mermaid)_(azur_lane)', 10], + ['new_jersey_(snow-white_ceremony)_(azur_lane)', 10], ['nonaka_kurumi', 10], + ['carmilla_(swimsuit_rider)_(third_ascension)_(fate)', 10], ['mal_(malberrybush)', 10], + ['rakugaki-chan', 10], ['azuma_(soft_voice_of_spring)_(azur_lane)', 10], ['reiko_(tofuubear)', 10], + ['sekhmet_of_death', 10], ['ty_lee', 10], ["iris_(en'en_no_shouboutai)", 10], + ['bremerton_(relaxation_consultation)_(azur_lane)', 10], + ['owari_(shimmering_forsythia)_(azur_lane)', 10], + ["drake_(the_golden_hind's_respite)_(azur_lane)", 10], ['komi_shuuko', 10], + ["yuigahama_yui's_mother", 10], ['amasawa_chigusa', 10], ['alex_(aestheticc-meme)', 10], + ['uzaki_yanagi', 10], ['nakabeni_yua', 10], ['strength_(black_rock_shooter)', 10], + ['unzen_(sojourn_through_clear_seas)_(azur_lane)', 10], ['bastet_(houtengeki)', 10], + ['yorra_villeneuve', 10], ['aikawa_ren', 10], ['io_(code_vein)', 10], + ['shinano_(dreamy_white_sands)_(azur_lane)', 10], ['elder_cousin_(igarashi_kyouhei)', 10], + ['tokage_setsuna', 10], ['chie_(ishikei)', 10], ['brown_haired_glasses_elf_(houtengeki)', 10], + ['elinalise_dragonroad', 10], ['sword_maiden', 10], ['regensburg_(azur_lane)', 10], + ['shinjin_succubus_(konosuba)', 10], ['marikawa_shizuka', 10], ['long-haired_girl_(motto_notto)', 10], + ['luna_(konosuba)', 10], ['hongryeon_(last_origin)', 10], ['micchan_(ohisashiburi)', 10], + ['sovetskaya_belorussiya_(relaxation_stratagem)_(azur_lane)', 10], ['musashi_(azur_lane)', 10], + ['tsubasa_(kureha)', 10], ['carol_olston', 10], ['hyuuga_hanabi', 10], ['sela_(23)', 10], + ['maki_oze', 10], ['sunao_(wokada)', 10], ['harukawa_syuria_(jack_dempa)', 10], + ['owari_(azur_lane)', 10], ['leonardo_da_vinci_(active_sailor)_(fate)', 10], + ['miyamae_shiho_(jack_dempa)', 10], ['tsuyuhara_miu', 10], ['nina_(wokada)', 10], + ['ariduka_formica', 10], ['implacable_(shepherd_of_the_"lost")_(azur_lane)', 10], ['rocoroco', 10], + ['ryuukyuu', 10], ['fia_the_deathbed_companion', 10], ['toujou_basara', 10], ['sera_(judgemint)', 10], + ['female_commander_(azur_lane)', 10], ['inui_shinju', 10], ['mass_production_eva', 10], + ['aloe_(ishuzoku_reviewers)', 10], ["aegir_(iron_blood's_dragon_maid)_(azur_lane)", 10], ['hinoa', 10], + ['hasegawa_chisato', 10], ['bakugou_mitsuki', 10], ['rapi_(nikke)', 10], ['tamaki_kotatsu', 10], + ['sakyumama_(kedama_milk)', 10], ['tomboy_childhood_friend_(cccpo)', 10], + ['alicia_renato_(yashiro_sousaku)', 10], ['moegi_homi', 10], ['south_dakota_(azur_lane)', 10], + ['sasaki_kanna_(kaedeko)', 10], ['vermeil_(kinsou_no_vermeil)', 10], ['goat-chan_(enarane)', 10], + ['saruei_(vtuber)', 10], ['carmilla_(swimsuit_rider)_(fate)', 10] +] + +rankIdentity = [ + ['vtuber', 20], ['accountant', 20], ['worker', 10], ['manager', 10], ['traffic_controller', 10], + ['airline_cabin_crew', 10], + ['art_therapist', 10], + ['arts_administrator', 10], ['auditor', 10], ['automotive_engineer', 10], ['barrister', 10], + ['band member', 10], ['maid', 15], ['teacher', 10], + ['student', 20], ['child_psychotherapist', 10], + ["nurse", 20], ['chiropractor', 10], + ['lawyer', 10], ['crystallographer', 10], ['curator', 10], + ['officer', 10], ['dancer', 10], + ['doctor_(general_practitioner,_gp)', 10], ['doctor_(hospital)', 10], ['dramatherapist', 10], + ['army', 15], ['firefighter', 10], ['chef', 15], + ['actress', 10], ['baker', 10], ['bellhop', 10], + ['blacksmith', 10], ['boxer', 10], ['butcher', 10], + ['carpenter', 10], ['cartoonist', 10], ['cashier', 10], + ['chemist', 10], ['clerk', 10], ['detective', 10], + ['engineer', 10], ['fisherman', 10], ['florist', 10], + ['flyer', 10], ['gardener', 10], ['guard', 10], + ['guide', 10], ['hiredresseer', 10], ['housekeeper', 10], + ['housewife', 10], ['janitor', 10], ['journalist', 10], ['hydrologist', 10], + ['illustrator', 10], ['masseuse', 10], ['model', 10], + + ['monk', 10], ['movie star', 10], ['musician', 10], + ['nun', 10], ['insurance_broker', 10], + + ['parachutist', 10], ['personnel', 10], ['photographer', 10], + ['interpreter', 10], ['postman', 10], ['processfor', 10], + ['tailor', 10], ['technician', 10], ['waiter', 20], + ['waitress', 50], ['journalist', 10], ['fisherman', 10], + ['vtuber', 90], ['landscape_architect', 10], ['learning_disability_nurse', 10], + ['midwife', 10], ['photographer', 10], ['police_officer', 10], + ['writer', 10], ['youth_worker', 10] +] + +rankMoods = [ + ['abandoned', 10], ['absent_minded', 10], ['abused', 10], ['accepted', 10], ['accomplished', 10], + ['accusatory', 10], ['accused', 10], ['admired', 10], ['adored', 10], ['adrift', 10], ['affectionate', 10], + ['afraid', 10], ['aggravated', 10], ['aggressive', 10], ['agitated', 10], ['alarmed', 10], ['alert', 10], + ['alienated', 10], ['alive', 10], ['alluring', 10], ['alone', 10], ['aloof', 10], ['amazed', 10], + ['ambushed', 10], ['amused', 10], ['angry', 10], ['annoyed', 10], ['antagonistic', 10], ['anxious', 10], + ['apathetic', 10], ['apologetic', 10], ['appalled', 10], ['appreciated', 10], ['appreciative', 10], + ['apprehensive', 10], ['aroused', 10], ['ashamed', 10], ['astonished', 10], ['attacked', 10], + ['attractive', 10], ['awake', 10], ['aware', 10], ['awe', 10], ['awed', 10], ['awestruck', 10], + ['awkward', 10], ['bad', 10], ['baffled', 10], ['barren', 10], ['bashful', 10], ['beaten', 10], + ['belittled', 10], ['benevolent', 10], ['berated', 10], ['betrayed', 10], ['bewildered', 10], + ['bitchy', 10], + ['bitter', 10], ['bittersweet', 10], ['blah', 10], ['blamed', 10], ['blank', 10], ['blissful', 10], + ['blue', 10], ['bold', 10], ['bored', 10], ['bothered', 10], ['bouncy', 10], ['brave', 10], ['broken', 10], + ['brooding', 10], ['bummed', 10], ['burdened', 10], ['burned-out', 10], ['callous', 10], ['calm', 10], + ['capable', 10], ['carefree', 10], ['careless', 10], ['caring', 10], ['caustic', 10], ['cautious', 10], + ['censored', 10], ['centered', 10], ['certain', 10], ['challenged', 10], ['charmed', 10], ['cheated', 10], + ['cheerful', 10], ['cherished', 10], ['childish', 10], ['chipper', 10], ['choleric', 10], ['clean', 10], + ['clear', 10], ['clever', 10], ['close', 10], ['closed', 10], ['clueless', 10], ['clumsy', 10], + ['cold', 10], + ['comfortable', 10], ['committed', 10], ['compassionate', 10], ['competent', 10], ['competitive', 10], + ['complacent', 10], ['complete', 10], ['concerned', 10], ['condemned', 10], ['condescension', 10], + ['confident', 10], ['confining', 10], ['confused', 10], ['considerate', 10], ['contemplative', 10], + ['contempt', 10], ['contemptuous', 10], ['content', 10], ['controlled', 10], ['conventional', 10], + ['convicted', 10], ['cornered', 10], ['courageous', 10], ['cowardly', 10], ['cranky', 10], ['crappy', 10], + ['crazy', 10], ['critical', 10], ['cross', 10], ['crushed', 10], ['curious', 10], ['cynical', 10], + ['daring', 10], ['dark', 10], ['dashed', 10], ['dazed', 10], ['dead', 10], ['deceived', 10], + ['dedicated', 10], + ['defeated', 10], ['defenseless', 10], ['defensive', 10], ['defiant', 10], ['degraded', 10], + ['dejected', 10], + ['delicate', 10], ['delighted', 10], ['demoralized', 10], ['dependent', 10], ['depressed', 10], + ['deprived', 10], ['derisive', 10], ['deserted', 10], ['desired', 10], ['desolate', 10], ['despair', 10], + ['desperate', 10], ['destroyed', 10], ['detached', 10], ['determined', 10], ['devastated', 10], + ['devious', 10], ['devoted', 10], ['didactic', 10], ['different', 10], ['difficult', 10], + ['dignified', 10], + ['dirty', 10], ['disappointed', 10], ['disbelieving', 10], ['discarded', 10], ['disconnected', 10], + ['discontent', 10], ['discontented', 10], ['discouraged', 10], ['disdainful', 10], ['disgraced', 10], + ['disgusted', 10], ['disheartened', 10], ['dishonest', 10], ['disillusioned', 10], ['dismal', 10], + ['dismayed', 10], ['disobedient', 10], ['disorganized', 10], ['disposable', 10], ['distant', 10], + ['distracted', 10], ['distressed', 10], ['disturbed', 10], ['ditzy', 10], ['dorky', 10], ['doubtful', 10], + ['down', 10], ['drained', 10], ['dreamy', 10], ['dreary', 10], ['dropped', 10], ['drunk', 10], + ['dull', 10], + ['dumb', 10], ['eager', 10], ['earnest', 10], ['ecstatic', 10], ['edgy', 10], ['effective', 10], + ['elated', 10], ['embarassed', 10], ['embarrassed', 10], ['empathetic', 10], ['empowered', 10], + ['empty', 10], + ['enchanted', 10], ['encouraged', 10], ['energetic', 10], ['energized', 10], ['enlightened', 10], + ['enraged', 10], ['enriched', 10], ['entertained', 10], ['enthralled', 10], ['enthusiastic', 10], + ['envious', 10], ['erudite', 10], ['evasive', 10], ['evil', 10], ['exasperated', 10], ['excited', 10], + ['excluded', 10], ['exhausted', 10], ['exhilarated', 10], ['expectant', 10], ['exploited', 10], + ['exposed', 10], ['exuberant', 10], ['faithful', 10], ['fake', 10], ['fanciful', 10], ['fantastic', 10], + ['fatalistic', 10], ['fatigued', 10], ['fearful', 10], ['fearless', 10], ['feisty', 10], ['fine', 10], + ['flirty', 10], ['flustered', 10], ['foolish', 10], ['foreboding', 10], ['forgiven', 10], + ['forgiving', 10], + ['forgotten', 10], ['forthright', 10], ['fortunate', 10], ['framed', 10], ['frantic', 10], ['free', 10], + ['friendly', 10], ['frightened', 10], ['frisky', 10], ['frustrated', 10], ['fulfilled', 10], ['full', 10], + ['funny', 10], ['furious', 10], ['futile', 10], ['geeky', 10], ['generous', 10], ['gentle', 10], + ['giddy', 10], + ['giggly', 10], ['giving', 10], ['glad', 10], ['gloomy', 10], ['glorious', 10], ['good', 10], + ['grateful', 10], + ['great', 10], ['grieving', 10], ['groggy', 10], ['grouchy', 10], ['grumpy', 10], ['guarded', 10], + ['guilty', 10], ['gullible', 10], ['handicapped', 10], ['happy', 10], ['harmonious', 10], ['hateful', 10], + ['haughty', 10], ['haunted', 10], ['haunting', 10], ['healthy', 10], ['heard', 10], ['heartbroken', 10], + ['heavy-hearted', 10], ['helpful', 10], ['helpless', 10], ['hesitant', 10], ['high', 10], ['honored', 10], + ['hopeful', 10], ['hopeless', 10], ['horrible', 10], ['horrified', 10], ['hospitable', 10], + ['hostile', 10], + ['hot', 10], ['humble', 10], ['humiliated', 10], ['hungry', 10], ['hurt', 10], ['hyper', 10], + ['hysterical', 10], ['idealistic', 10], ['idiotic', 10], ['idyllic', 10], ['ignorant', 10], + ['ignored', 10], + ['imaginative', 10], ['immune', 10], ['impatient', 10], ['impelled', 10], ['imperfect', 10], + ['impertinent', 10], ['important', 10], ['impressed', 10], ['impulsive', 10], ['inadequate', 10], + ['inattentive', 10], ['incensed', 10], ['inclusive', 10], ['incompetent', 10], ['incomplete', 10], + ['incredulous', 10], ['indebted', 10], ['indecisive', 10], ['independent', 10], ['indescribable', 10], + ['indifferent', 10], ['indignant', 10], ['industrious', 10], ['inept', 10], ['inferior', 10], + ['inflated', 10], + ['informed', 10], ['infuriated', 10], ['inhibited', 10], ['innocent', 10], ['innovative', 10], + ['inquisitive', 10], ['insane', 10], ['insecure', 10], ['insensitive', 10], ['insidious', 10], + ['insignificant', 10], ['insulted', 10], ['intense', 10], ['interested', 10], ['interrogated', 10], + ['interrupted', 10], ['intimate', 10], ['intimidated', 10], ['intrigued', 10], ['invigorated', 10], + ['invisible', 10], ['involved', 10], ['irate', 10], ['irked', 10], ['irrational', 10], + ['irresponsible', 10], + ['irritated', 10], ['isolated', 10], ['jaded', 10], ['jealous', 10], ['jinxed', 10], ['jolly', 10], + ['jovial', 10], ['joyful', 10], ['joyous', 10], ['jubilant', 10], ['judged', 10], ['judgmental', 10], + ['jumpy', 10], ['just', 10], ['justified', 10], ['kidded', 10], ['kind', 10], ['knowledgeable', 10], + ['late', 10], ['lazy', 10], ['leery', 10], ['left', 10], ['let', 10], ['lethargic', 10], ['liable', 10], + ['liberated', 10], ['liberating', 10], ['lifeless', 10], ['light-hearted', 10], ['liked', 10], + ['listened', 10], ['listless', 10], ['logical', 10], ['lonely', 10], ['loose', 10], ['lost', 10], + ['lousy', 10], ['lovable', 10], ['loved', 10], ['loving', 10], ['lucky', 10], ['lyrical', 10], ['mad', 10], + ['malicious', 10], ['manipulated', 10], ['matter', 10], ['fact', 10], ['mean', 10], ['meditative', 10], + ['melancholic', 10], ['melancholy', 10], ['mellow', 10], ['merciless', 10], ['merry', 10], + ['mischievous', 10], + ['miserable', 10], ['misinterpreted', 10], ['mistreated', 10], ['misunderstood', 10], ['mixed', 10], + ['mocked', 10], ['mocking', 10], ['modest', 10], ['molested', 10], ['moody', 10], ['morose', 10], + ['motivated', 10], ['mournful', 10], ['moved', 10], ['mystified', 10], ['naive', 10], ['nasty', 10], + ['naughty', 10], ['nauseated', 10], ['needed', 10], ['needy', 10], ['negative', 10], ['neglected', 10], + ['nerdy', 10], ['nervous', 10], ['neurotic', 10], ['nightmarish', 10], ['nonchalant', 10], + ['nostalgic', 10], + ['not', 10], ['specified', 10], ['noticed', 10], ['numb', 10], ['obeyed', 10], ['objective', 10], + ['obligated', 10], ['obvious', 10], ['odd', 10], ['offended', 10], ['okay', 10], ['old', 10], ['open', 10], + ['oppressed', 10], ['optimistic', 10], ['ornery', 10], ['control', 10], ['outraged', 10], ['overcome', 10], + ['overjoyed', 10], ['overloaded', 10], ['overwhelmed', 10], ['overworked', 10], ['owned', 10], + ['painful', 10], + ['pampered', 10], ['panicky', 10], ['paralyzed', 10], ['passionate', 10], ['passive', 10], ['patient', 10], + ['patronizing', 10], ['peaceful', 10], ['peeved', 10], ['pensive', 10], ['perky', 10], ['perplexed', 10], + ['persecuted', 10], ['pessimistic', 10], ['pestered', 10], ['petrified', 10], ['petty', 10], ['phony', 10], + ['pious', 10], ['pissed', 10], ['off', 10], ['playful', 10], ['pleased', 10], ['poor', 10], + ['positive', 10], + ['possessive', 10], ['powerful', 10], ['powerless', 10], ['practical', 10], ['predatory', 10], + ['pressured', 10], ['private', 10], ['productive', 10], ['protected', 10], ['protective', 10], + ['proud', 10], + ['provoked', 10], ['prudish', 10], ['punished', 10], ['pushy', 10], ['puzzled', 10], ['questioned', 10], + ['quiet', 10], ['quixotic', 10], ['quizzical', 10], ['rambunctious', 10], ['realistic', 10], + ['reassured', 10], + ['rebellious', 10], ['reborn', 10], ['receptive', 10], ['reckless', 10], ['recognized', 10], + ['reconciled', 10], ['recumbent', 10], ['reflective', 10], ['refreshed', 10], ['regretful', 10], + ['rejected', 10], ['rejuvenated', 10], ['relaxed', 10], ['released', 10], ['relieved', 10], + ['reluctant', 10], + ['reminiscent', 10], ['remorse', 10], ['renewed', 10], ['replaced', 10], ['replenished', 10], + ['repressed', 10], ['rescued', 10], ['resentful', 10], ['reserved', 10], ['resistant', 10], + ['resourceful', 10], ['respected', 10], ['responsible', 10], ['restless', 10], ['restricted', 10], + ['revengeful', 10], ['reverent', 10], ['revitalized', 10], ['ribald', 10], ['rich', 10], ['ridicule', 10], + ['ridiculous', 10], ['right', 10], ['rigid', 10], ['robbed', 10], ['romantic', 10], ['rotten', 10], + ['rushed', 10], ['sabotaged', 10], ['sad', 10], ['safe', 10], ['sarcastic', 10], ['sardonic', 10], + ['sassy', 10], ['satiated', 10], ['satiric', 10], ['satisfied', 10], ['saved', 10], ['scared', 10], + ['scolded', 10], ['scorned', 10], ['secure', 10], ['seductive', 10], ['selfish', 10], ['self-assured', 10], + ['self-centered', 10], ['self-confident', 10], ['self-conscious', 10], ['self-destructive', 10], + ['self-reliant', 10], ['sensitive', 10], ['sentimental', 10], ['serene', 10], ['serious', 10], + ['sexy', 10], + ['shaken', 10], ['shamed', 10], ['sheepish', 10], ['shocked', 10], ['shunned', 10], ['shy', 10], + ['sick', 10], + ['silenced', 10], ['silly', 10], ['sincere', 10], ['sinful', 10], ['skeptical', 10], ['skillful', 10], + ['slandered', 10], ['sleepy', 10], ['sluggish', 10], ['small', 10], ['smart', 10], ['smothered', 10], + ['solemn', 10], ['somber', 10], ['soothed', 10], ['sorry', 10], ['special', 10], ['spiteful', 10], + ['splendid', 10], ['spunky', 10], ['squashed', 10], ['stifled', 10], ['stimulated', 10], ['stingy', 10], + ['strained', 10], ['stressed', 10], ['stretched', 10], ['strong', 10], ['stubborn', 10], ['stumped', 10], + ['stunned', 10], ['stupid', 10], ['submissive', 10], ['successful', 10], ['suffocated', 10], + ['suicidal', 10], + ['sullen', 10], ['sunk', 10], ['super', 10], ['superior', 10], ['supported', 10], ['sure', 10], + ['surly', 10], + ['surprised', 10], ['suspenseful', 10], ['suspicious', 10], ['sympathetic', 10], ['tacky', 10], + ['tactful', 10], ['talented', 10], ['talkative', 10], ['tame', 10], ['tarnished', 10], ['tasteful', 10], + ['tearful', 10], ['teased', 10], ['tenacious', 10], ['tender', 10], ['tense', 10], ['tepid', 10], + ['terrible', 10], ['terrific', 10], ['terrified', 10], ['terrifying', 10], ['tested', 10], ['testy', 10], + ['thankful', 10], ['thoughtful', 10], ['threatened', 10], ['threatening', 10], ['thrifty', 10], + ['thrilled', 10], ['tired', 10], ['tormented', 10], ['torn', 10], ['tortured', 10], ['touched', 10], + ['tough', 10], ['tragic', 10], ['tranquil', 10], ['transformed', 10], ['trapped', 10], ['treasured', 10], + ['trembly', 10], ['tremendous', 10], ['tricked', 10], ['troubled', 10], ['trusted', 10], ['trustful', 10], + ['ugly', 10], ['unaccepted', 10], ['unappreciated', 10], ['unbalanced', 10], ['unburdened', 10], + ['uncanny', 10], ['uncomfortable', 10], ['unconcerned', 10], ['uneven', 10], ['unfit', 10], + ['unfriendly', 10], + ['united', 10], ['unjust', 10], ['unknown', 10], ['unneeded', 10], ['unpleasant', 10], ['unreal', 10], + ['unruly', 10], ['unwise', 10], ['up', 10], ['uplifted', 10], ['used', 10], ['useless', 10], + ['vacant', 10], + ['vague', 10], ['vain', 10], ['valid', 10], ['valued', 10], ['vengeful', 10], ['vexed', 10], + ['vicious', 10], + ['victimized', 10], ['victorious', 10], ['violated', 10], ['violent', 10], ['vivacious', 10], + ['vivid', 10], + ['void', 10], ['wacky', 10], ['warlike', 10], ['warm', 10], ['warmhearted', 10], ['warned', 10], + ['wary', 10], + ['wasted', 10], ['weak', 10], ['wealthy', 10], ['weary', 10], ['weird', 10], ['welcoming', 10], + ['whimsical', 10], ['whole', 10], ['wild', 10], ['willful', 10], ['wishful', 10], ['witty', 10], + ['worldly', 10], ['worried', 10], ['worse', 10], ['worthy', 10], ['wounded', 10], ['wrong', 10], + ['yearning', 10], ['yellow', 10], ['yielding', 10], ['young', 10], ['youthful', 10], ['zany', 10], + ['zealous', 10] +] diff --git a/src/novelai_python/utils/random_prompt/tag_nsfw.py b/src/novelai_python/utils/random_prompt/tag_nsfw.py index 826ba56..f27fcb6 100644 --- a/src/novelai_python/utils/random_prompt/tag_nsfw.py +++ b/src/novelai_python/utils/random_prompt/tag_nsfw.py @@ -966,3 +966,19 @@ "nw": "nsfw" } +if __name__ == "__main__": + + # 获取tags列表 + tags = [] + for key, value in nsfw.items(): + if not key.startswith('_') and key != 'var': + tags.extend(value) + print(tags) + + # 展开二级列表 + tags = [tag[0] for tag in tags] + print(tags) + import json + + with open('../../../../playground/cos/tag_nsfw.json', 'w') as f: + json.dump(tags, f) From 303485230c5a8fdc68f5eeced5a758c79b4278d4 Mon Sep 17 00:00:00 2001 From: sudoskys Date: Wed, 7 Feb 2024 18:45:51 +0800 Subject: [PATCH 2/3] :sparkles: feat(server): Add user login endpoint Added a new endpoint for user login in the server.py file. The login endpoint allows users to log in and returns the result. If any error occurs during the login process, an exception is logged and a 500 status code is returned. The new endpoint is defined as a POST request at `/user/login`. The request body expects a `Login` object. --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8be76a6..d3c14c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "novelai-python" -version = "0.1.9" +version = "0.2.0" description = "Novelai Python Binding With Pydantic" authors = [ { name = "sudoskys", email = "coldlando@hotmail.com" }, From 7decb390d13be9faafec9b4a6ccd93f3ccb42297 Mon Sep 17 00:00:00 2001 From: sudoskys Date: Wed, 7 Feb 2024 19:01:46 +0800 Subject: [PATCH 3/3] :recycle: chore(utils/random_prompt): disable enable_character in generate() --- src/novelai_python/utils/random_prompt/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/novelai_python/utils/random_prompt/__init__.py b/src/novelai_python/utils/random_prompt/__init__.py index dbd63b3..5469481 100644 --- a/src/novelai_python/utils/random_prompt/__init__.py +++ b/src/novelai_python/utils/random_prompt/__init__.py @@ -167,7 +167,7 @@ def character_features(self, gender, camera_angle, nsfw_enabled, num_characters, def generate(self, *, enable_moods: bool = True, - enable_character: bool = True, + enable_character: bool = False, enable_identity: bool = True, ): """