Skip to content

Commit eefdec8

Browse files
committed
Merge branch 'dev'
2 parents eb6d656 + 4348ca3 commit eefdec8

27 files changed

+2812
-1811
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ __pycache__
55
my_*.json
66
auth/*
77
cache*.json
8-
tag_cache.dat
8+
*.dat
99
venv

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
### 2024-10-29
2+
3+
**1.1.0** release
4+
* Added [Danbooru](https://danbooru.donmai.us) as tag source
5+
* Added support for [SeaArt Furry XL V1](https://civitai.com/models/391781/seaart-furry-xl-10) model
6+
* Import/Export functions for prompts and filters
7+
* Prompt info panel is now more compact and readable
8+
* Minor ComfyUI nodes improvements (notably: updater dummy is no longer needed)
9+
* Tons of refactoring and behind-the-scene improvements
10+
111
### 2024-07-03
212

313
**1.0.0 release**

README.md

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
# Lazy Pony Prompter
22

3-
A booru API powered prompt generator for [AUTOMATIC1111's Stable Diffusion Web UI](https://github.com/AUTOMATIC1111/stable-diffusion-webui) and [ComfyUI](https://github.com/comfyanonymous/ComfyUI) with flexible tag filtering system and customizable prompt templates.
3+
A booru API powered prompt generator for [AUTOMATIC1111's Stable Diffusion Web UI](https://github.com/AUTOMATIC1111/stable-diffusion-webui) / [Forge](https://github.com/lllyasviel/stable-diffusion-webui-forge) and [ComfyUI](https://github.com/comfyanonymous/ComfyUI) with flexible tag filtering system and customizable prompt templates.
44

55
Supported boorus/websites:
66
* [Derpibooru](https://derpibooru.org)
77
* [E621](https://e621.net)
8-
* More coming soon™
8+
* [Danbooru](https://danbooru.donmai.us)
9+
* More coming soon™ (or not ;))
910

1011
> [!IMPORTANT]
11-
> **1.0.0 release highlights:**
12-
> * Overhauled UI
13-
> * New tag filtering system with filter management and pattern substitutions
14-
> * Filter prompts by content rating (Safe/Questionable/Explicit)
15-
> * Increased maximum prompts fetching limit to 1500
16-
> * Improved status reporting and logging
17-
> * See [Filter Editor](#filter-editor) for converting legacy filter strings to new format
12+
>
13+
> **1.1.0 release highlights:**
14+
> * Added [Danbooru](https://danbooru.donmai.us) as tag source
15+
> * Added support for [SeaArt Furry XL V1](https://civitai.com/models/391781/seaart-furry-xl-10) model
16+
> * Import/Export functions for prompts and filters
17+
> * Prompt info panel is now more compact and readable
18+
> * Minor ComfyUI nodes improvements (notably: updater dummy is no longer needed)
19+
> * Tons of refactoring and behind-the-scene improvements
1820
1921
Derpibooru + [Pony Diffusion V6 XL](https://civitai.com/models/257749?modelVersionId=290640) + [PD Styles Collection](https://github.com/Siberpone/pd-styles) (which I highly recommend you also check out) samples:
2022

@@ -29,11 +31,13 @@ E621 + [EasyFluff](https://civitai.com/models/129996/easyfluff) samples:
2931
# Installation
3032

3133
### ❗Requirements
32-
* [AUTOMATIC1111's Stable Diffusion Web UI](https://github.com/AUTOMATIC1111/stable-diffusion-webui) or [ComfyUI](https://github.com/comfyanonymous/ComfyUI);
34+
* [AUTOMATIC1111's Stable Diffusion Web UI](https://github.com/AUTOMATIC1111/stable-diffusion-webui) / [Forge](https://github.com/lllyasviel/stable-diffusion-webui-forge) or [ComfyUI](https://github.com/comfyanonymous/ComfyUI);
3335
* One of recommended models (these are the "officially" supported models, but LPP should work well for other tag-based models as long as their "native" booru is used as tag source):
3436
* [Pony Diffusion V6 XL](https://civitai.com/models/257749?modelVersionId=290640);
35-
* [EasyFluff](https://civitai.com/models/129996/easyfluff);
3637
* [Pony Diffusion V5(.5)](https://civitai.com/models/95367/pony-diffusion-v5);
38+
* [EasyFluff](https://civitai.com/models/129996/easyfluff);
39+
* [SeaArt Furry XL V1](https://civitai.com/models/391781/seaart-furry-xl-10);
40+
* [AutismMix](https://civitai.com/models/288584);
3741
* Active internet connection for communication with boorus;
3842
* *(optional)* [Derpibooru](https://derpibooru.org) account for extra functionality.
3943

@@ -48,7 +52,7 @@ Click "Install" and after it's finished installing, restart the server. You shou
4852

4953
### 🛏 ComfyUI
5054

51-
Clone this repository to `.../ComfyUI/custom_nodes`
55+
You can install LPP via [ComfyUI Manager](https://github.com/ltdrdata/ComfyUI-Manager) or manually by cloning this repository to `.../ComfyUI/custom_nodes`
5256

5357
### 🙌 Manual
5458
Clone this repository with:
@@ -92,7 +96,7 @@ On this panel you can pull tag data from selected booru site by typing in or pas
9296
* **Derpibooru specific:**
9397
* *Derpibooru Filter* - will apply this [Derpibooru filter](https://derpibooru.org/filters) to the query. Only system filters are available by default. If you want to use your personal filters, you must provide an [API key](#-api-key);
9498
* *Sort by* - type of sorting to apply to the query. Wilson Score is the default.
95-
* **E621 specific:**
99+
* **E621 and Danbooru specific:**
96100
* *Rating* - will append selected rating tag to the query.
97101
* *Sort by* - will append selected sorting type tag to the query.
98102

@@ -125,7 +129,9 @@ And last but not least for the filtering system is the `Rating Filter`. It allow
125129

126130
![Filter Editor](images/filters_editor.jpg)
127131

128-
This tab is used to manage and edit your persistent filters that can then be applied to LPP-generated prompts via selecting them in the `Filters` input on the "Prompts Manager" tab. On the left you'll find the `Create or delete a filter` input that is used to manage your filters: type in a new name for a filter and click the ✨ to create a new filter or select an existing filter form a drop-down list and click the ❌ to delete it. The `Import Legacy Filters` button underneath is used to convert your pre-1.0.0 saved filter strings to the new system. It will create a new persistent filter for each prompt collection that has legacy filter string attached to it and automatically add it to the collection's autoload list. You only need to run this once.
132+
This tab is used to manage and edit your persistent filters that can then be applied to LPP-generated prompts via selecting them in the `Filters` input on the "Prompts Manager" tab. On the left you'll find the `Create or delete a filter` input that is used to manage your filters: type in a new name for a filter and click the ✨ to create a new filter or select an existing filter form a drop-down list and click the ❌ to delete it.
133+
134+
Below, you'll find the file drop area for importing and exporting your locally saved prompts and filters. You can export them by clicking the "Export Prompts and Filters" button and then downloading the json file from file drop area. You can import prompts and filters data by dragging the previously exported json file onto the file drop area. If there is a naming conflict between already existing items and items that are being imported, the existing items take precedence.
129135

130136
Next you'll find a number of identical filter editors that are used to edit the filters. You can adjust the number of editors in the LPP's section of A1111 settings. To load up a filter, simply choose it from a drop-down in any of the editors (hit the 🗘 button if the desired filter doesn't appear on the list) and start editing the filter patterns. The syntax is exactly the same as described in the [Filtering System](#-filtering-system), but patterns are separated with new lines. Click the 💾 button to save changes to the filter.
131137

@@ -213,18 +219,18 @@ LPP nodes are available under `LPP` group. The interface and functionality are k
213219

214220
To further personalize your queries you can provide LPP with your personal Derpibooru API key (requires Derpibooru account). This will enable LPP to use your personal [Derpibooru filters](https://derpibooru.org/filters) and access images from your watch list by including `my:watched` into your queries. To provide an API key, go to `Settings -> Lazy Pony Prompter` and paste the key into the respective textbox. Then click "Apply settings" and reload UI. You can obtain an API key from your Derpibooru account info page (hover over your user icon -> Account).
215221

216-
# Pro Tips & Potential Pitfalls
222+
# Pro Tips & Fun Facts
217223
* 🐞 Found a bug? Create an [issue](https://github.com/Siberpone/lazy-pony-prompter/issues).
218224
* 💬 Want to request a feature or have suggestions on how to improve the extension? Open up a [discussion](https://github.com/Siberpone/lazy-pony-prompter/discussions).
219225
* You can see the latest additions to LPP in the [Changelog](CHANGELOG.md).
220226
* You can use A1111's "Defaults" feature to customize LPP UI default values (Settings -> Defaults).
221227
* LPP works best with images with high upvote/score count as those tend to be the most fully and properly tagged.
222228
* LPP overrides webui prompts processing completely and, thus, not compatible with dynamic prompting extensions (you don't have to uninstall them or anything, just don't run them simultaneously with LPP).
223229
* LPP is very light on traffic since it uses the website's API and only pulls necessary text data and not the actual webpages or images.
224-
* Your saved prompts are stored in `tag_cache.dat` file in the root extension directory.
230+
* Use Export prompts and filters feature to create backups of your locally stored data or share it with friends!
225231
* Useful links:
226-
* [purplesmart.ai](https://purplesmart.ai) aka PSAI - V5 creators website with gallery and prompt examples.
227-
* [PSAI Discord server](http://discord.gg/94KqBcE) - poni AI discussion, help, tech support and free V5 bot.
232+
* [CivitAI](https://civitai.com/) - *the* AI art website. And [small magical horses themed art](https://civitai.com/user/Siberpone/posts) by yours truly on the aforementioned website ;)
233+
* [purplesmart.ai](https://purplesmart.ai) aka PSAI - Pony Diffusion creators website with gallery and prompt examples.
234+
* [PSAI Discord server](http://discord.gg/94KqBcE) - poni AI discussion, help, tech support and free V6 bot.
228235
* [EasyFluff](https://civitai.com/models/129996/easyfluff)
229-
* [Stable Diffusion Guides Collection](https://rentry.org/sdgoldmine)
230236
* 🐎 Please, poni responsibly 🐴🦄🪶.

__init__.py

Lines changed: 10 additions & 200 deletions
Original file line numberDiff line numberDiff line change
@@ -1,219 +1,29 @@
1-
import sys
2-
from os.path import dirname
3-
from copy import deepcopy
4-
from random import randint
5-
LPP_ROOT_DIR = dirname(__file__)
6-
sys.path.append(LPP_ROOT_DIR)
7-
8-
from .lpp.sources import Derpibooru, E621
9-
from .lpp.backend import SourcesManager, PromptsManager, CacheManager
10-
11-
sm = SourcesManager(LPP_ROOT_DIR)
12-
cm = CacheManager(LPP_ROOT_DIR)
13-
14-
15-
class ComfyTagSourceBase:
16-
tag_source_input_types_base = {
17-
"required": {
18-
"query": ("STRING", {
19-
"multiline": True
20-
}),
21-
"tag_filter": ("STRING", {
22-
"multiline": False
23-
}),
24-
"count": ("INT", {
25-
"default": 100,
26-
"min": 5,
27-
"max": 300,
28-
"step": 5,
29-
"display": "slider"
30-
}),
31-
"send_request": ("BOOLEAN", {
32-
"default": False
33-
})
34-
},
35-
"optional": {
36-
"update_dummy": ("INT", {
37-
"default": 0,
38-
"min": 0,
39-
"max": 0xffffffffffffffff,
40-
}),
41-
"prompt_template": ("STRING", {
42-
"multiline": False
43-
})
44-
}
45-
}
46-
47-
def __init__(self, source):
48-
self._sm: SourcesManager = SourcesManager(LPP_ROOT_DIR, [source])
49-
self._pm: PromptsManager = PromptsManager(self._sm)
50-
51-
RETURN_TYPES = ("STRING", "LPP_TAG_DATA")
52-
RETURN_NAMES = ("Prompt", "LPP Tag Data")
53-
CATEGORY = "LPP/sources"
54-
FUNCTION = "get_prompt"
55-
56-
def get_prompt(self):
57-
pass
58-
59-
60-
class ComfyDerpibooru(ComfyTagSourceBase):
61-
def __init__(self):
62-
ComfyTagSourceBase.__init__(self, Derpibooru)
63-
64-
@classmethod
65-
def INPUT_TYPES(self):
66-
types = deepcopy(self.tag_source_input_types_base)
67-
types["required"]["filter"] = (sm.sources["Derpibooru"].get_filters(),)
68-
types["required"]["sort_by"] = (sm.sources["Derpibooru"].get_sort_options(),)
69-
types["required"]["format"] = (sm.sources["Derpibooru"].get_model_names(),)
70-
types["optional"]["tag_data"] = ("LPP_TAG_DATA_DERPIBOORU",)
71-
return types
72-
73-
def get_prompt(
74-
self, query, count, filter, sort_by, format, tag_filter,
75-
send_request, tag_data=None, update_dummy=0, prompt_template=""
76-
):
77-
if tag_data:
78-
self._pm.tag_data = tag_data
79-
elif self._pm.get_loaded_prompts_count() == 0 or send_request:
80-
self._pm.tag_data = self._sm.request_prompts(
81-
"Derpibooru", query, count, filter, sort_by
82-
)
83-
return (
84-
self._pm.choose_prompts(format, prompt_template, 1, tag_filter)[0],
85-
(self._pm.tag_data, tag_filter)
86-
)
87-
88-
89-
class ComfyE621(ComfyTagSourceBase):
90-
def __init__(self):
91-
ComfyTagSourceBase.__init__(self, E621)
92-
93-
@classmethod
94-
def INPUT_TYPES(self):
95-
types = deepcopy(self.tag_source_input_types_base)
96-
types["required"]["rating"] = (sm.sources["E621"].get_ratings(),)
97-
types["required"]["sort_by"] = (sm.sources["E621"].get_sort_options(),)
98-
types["required"]["format"] = (sm.sources["E621"].get_model_names(),)
99-
types["optional"]["tag_data"] = ("LPP_TAG_DATA_E621",)
100-
return types
101-
102-
def get_prompt(
103-
self, query, count, rating, sort_by, format, tag_filter,
104-
send_request, tag_data=None, update_dummy=0, prompt_template=""
105-
):
106-
if tag_data:
107-
self._pm.tag_data = tag_data
108-
elif self._pm.get_loaded_prompts_count() == 0 or send_request:
109-
self._pm.tag_data = self._sm.request_prompts(
110-
"E621", query, count, rating, sort_by
111-
)
112-
return (
113-
self._pm.choose_prompts(format, prompt_template, 1, tag_filter)[0],
114-
(self._pm.tag_data, tag_filter)
115-
)
116-
117-
118-
class LPPSaver:
119-
@classmethod
120-
def INPUT_TYPES(self):
121-
return {
122-
"required": {
123-
"tag_data": ("LPP_TAG_DATA",),
124-
"name": ("STRING", {
125-
"multiline": False,
126-
}),
127-
"overwrite": ("BOOLEAN", {
128-
"default": False
129-
})
130-
}
131-
}
132-
RETURN_TYPES = ()
133-
CATEGORY = "LPP"
134-
FUNCTION = "save_tag_data"
135-
OUTPUT_NODE = True
136-
137-
def save_tag_data(self, tag_data, name, overwrite):
138-
existing_names = cm.get_saved_names()
139-
if (name in existing_names and overwrite) \
140-
or name not in existing_names:
141-
cm.cache_tag_data(name, tag_data[0], tag_data[1])
142-
return {}
143-
144-
145-
class ForceRunBase:
146-
@classmethod
147-
def IS_CHANGED(self):
148-
return randint(0, 0xffffffffffffffff)
149-
150-
151-
class LPPLoaderDerpibooru(ForceRunBase):
152-
@classmethod
153-
def INPUT_TYPES(self):
154-
return {
155-
"required": {
156-
"collection_name": (cm.get_saved_names("Derpibooru"),)
157-
}
158-
}
159-
RETURN_TYPES = ("LPP_TAG_DATA_DERPIBOORU",)
160-
RETURN_NAMES = ("tag data",)
161-
CATEGORY = "LPP/loaders"
162-
FUNCTION = "load_tag_data"
163-
164-
def load_tag_data(self, collection_name):
165-
return (cm.get_tag_data(collection_name),)
166-
167-
168-
class LPPLoaderE621(ForceRunBase):
169-
@classmethod
170-
def INPUT_TYPES(self):
171-
return {
172-
"required": {
173-
"collection_name": (cm.get_saved_names("E621"),)
174-
}
175-
}
176-
RETURN_TYPES = ("LPP_TAG_DATA_E621",)
177-
RETURN_NAMES = ("tag data",)
178-
CATEGORY = "LPP/loaders"
179-
FUNCTION = "load_tag_data"
180-
181-
def load_tag_data(self, collection_name):
182-
return (cm.get_tag_data(collection_name),)
183-
184-
185-
class LPPDeleter(ForceRunBase):
186-
@classmethod
187-
def INPUT_TYPES(self):
188-
return {
189-
"required": {
190-
"collection_name": (cm.get_saved_names(),)
191-
}
192-
}
193-
RETURN_TYPES = ()
194-
CATEGORY = "LPP"
195-
FUNCTION = "delete_tag_data"
196-
OUTPUT_NODE = True
197-
198-
def delete_tag_data(self, collection_name):
199-
cm.delete_tag_data(collection_name)
200-
return {}
1+
from .lpp.ui.comfy import ComfyDerpibooru, LPPLoaderDerpibooru
2+
from .lpp.ui.comfy import ComfyE621, LPPLoaderE621
3+
from .lpp.ui.comfy import ComfyDanbooru, LPPLoaderDanbooru
4+
from .lpp.ui.comfy import LPPSaver, LPPDeleter
2015

2026

2037
NODE_CLASS_MAPPINGS = {
2048
"LPP_Derpibooru": ComfyDerpibooru,
2059
"LPP_E621": ComfyE621,
10+
"LPP_Danbooru": ComfyDanbooru,
20611
"LPP_Saver": LPPSaver,
20712
"LPP_Loader_Derpibooru": LPPLoaderDerpibooru,
20813
"LPP_Loader_E621": LPPLoaderE621,
14+
"LPP_Loader_Danbooru": LPPLoaderDanbooru,
20915
"LPP_Deleter": LPPDeleter
21016
}
21117

21218
NODE_DISPLAY_NAME_MAPPINGS = {
21319
"LPP_Derpibooru": "Derpibooru",
21420
"LPP_E621": "E621",
21+
"LPP_Danbooru": "Danbooru",
21522
"LPP_Saver": "Tag Data Saver",
21623
"LPP_Loader_Derpibooru": "Tag Data Loader (Derpibooru)",
21724
"LPP_Loader_E621": "Tag Data Loader (E621)",
25+
"LPP_Loader_Danbooru": "Tag Data Loader (Danbooru)",
21826
"LPP_Deleter": "Tag Data Deleter"
21927
}
28+
29+
__all__ = [NODE_CLASS_MAPPINGS]

0 commit comments

Comments
 (0)