{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "id": "DvR1ftP44Mky" }, "outputs": [], "source": [ "# aWaifu - random waifu generator, run in Google Colab\n", "# Aki Hakune, October 27th 2021" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "qM92sH505hTa" }, "outputs": [], "source": [ "# Turn these on if you are too lazy to read the code\n", "autoRun = False\n", "autoSave = False\n", "verbose = False" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "SKf8HnBkIHg9" }, "outputs": [], "source": [ "!pip install -q Waifulabs\n", "import waifulabs\n", "import cv2\n", "import time\n", "import os\n", "import requests\n", "import shutil\n", "import json\n", "import random\n", "from typing import Dict\n", "from google.colab.patches import cv2_imshow\n", "from google.colab import files" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "eDemmJEnIf1C" }, "outputs": [], "source": [ "class Waifus:\n", " def __init__ (self, outputPath:str = 'waifus/',\n", " numberOfProfiles:int = 10,\n", " verbosity:bool = False,\n", " bigWaifu:bool = False,\n", " noProfile:bool = False,\n", " noImage:bool = False):\n", " self.dataPath = outputPath\n", " self.numberOfProfiles:int = numberOfProfiles\n", " self.verbose:bool = verbosity\n", " self.bigWaifu:bool = bigWaifu\n", " self.noProfile = noProfile\n", " self.noImage = noImage\n", "\n", "\n", " # Methods are arranged from more public -> more private ones\n", " # The last method is an exception, as it's the main method of this class\n", "\n", "\n", " @staticmethod\n", " def cleanUpPreviousRuns() -> None:\n", " \"\"\"Delete data from previous executions\"\"\"\n", " defaultDataDir:str = 'waifus'\n", " shutil.rmtree(defaultDataDir, ignore_errors=True)\n", "\n", "\n", " @staticmethod\n", " def showWaifuImages() -> None:\n", " waifuImageDir:str = 'waifus'\n", "\n", " if os.path.isdir(waifuImageDir):\n", " for filename in os.listdir(waifuImageDir):\n", " if filename.startswith('waifu-') or filename.endswith('.png'):\n", " imagePath:str = waifuImageDir + '/' + filename\n", " print(f\"Showing: {imagePath}\\n\")\n", " img = cv2.imread(imagePath, -1)\n", " cv2_imshow(img)\n", " print('\\n\\n\\n')\n", " \n", " else:\n", " raise FileNotFoundError(\"Make sure that you've generated some profiles\")\n", "\n", " \n", " @staticmethod\n", " def getAllInfo() -> None:\n", " \"\"\"Download every generated information under zipped format\"\"\"\n", " try:\n", " shutil.make_archive('waifus', 'zip', 'waifus')\n", " except FileNotFoundError:\n", " print(\"Please make sure that you have generated 'waifus' directory first.\")\n", " return None\n", " \n", " print('Zipping files... Please patiently wait...', end='\\r')\n", " files.download('waifus.zip') # might not work in Firefox\n", "\n", "\n", " @staticmethod\n", " def getRandomAge() -> None:\n", " \"\"\"Generate completely random, unrelated age\"\"\"\n", " return random.choice([\n", " random.randint(3, 25), # age of human waifu\n", " random.randint(10**3, 10**5) # age of non-human waifu\n", " ])\n", "\n", "\n", " @staticmethod\n", " def getRandomRace(age:int) -> str:\n", " \"\"\"Randomizing a race\"\"\"\n", " # TODO: Add more races\n", " # TODO: Load from external sources\n", " humanHighestAge:int = 25\n", " NON_HUMAN_RACES = ['Dark Hagravens', 'Demi Fiends', 'Lost Nymphs', 'Forlorn Hags', 'Highborn Fiends', 'Elemental Hydra', 'Bog Nymphs', 'Shard Undine', 'Velvet People', 'Western Fairies', 'Forest Elf', 'Frost Dwarf', 'Demon', 'Dragonman', 'Fairy', 'Fire Soul', 'Half-Elf', 'High Elf', 'Lamia', 'Moon Elf', 'Night Elf']\n", "\n", " if age > humanHighestAge:\n", " return random.choice(NON_HUMAN_RACES)\n", " return random.choice(['Human', random.choice(NON_HUMAN_RACES)])\n", "\n", "\n", " def _vbose(self, contextType:str, context) -> None:\n", " \"\"\"Logging, verbose messages and image showing\"\"\"\n", " if self.verbose:\n", " if contextType == 'text':\n", " print(context, end='\\n')\n", " elif contextType == 'image':\n", " img = cv2.imread(context, -1)\n", " cv2_imshow(img)\n", " print('\\n\\n\\n')\n", " elif contextType == 'dictionary':\n", " print(json.dumps(context, indent=4, ensure_ascii=False))\n", " print()\n", " else:\n", " print(f\"Unknown type logging: {context}\")\n", "\n", "\n", " def _getRandomProfile(self, imagePath:str) -> 'json data':\n", " \"\"\"Generate random profile\"\"\"\n", "\n", " profileDataPath:str = self.dataPath + 'profile.json'\n", "\n", " # Using free, no-authentication Name Fake API\n", " apiHost:str = 'https://api.namefake.com'\n", " endPoint:str = apiHost + '/random/female'\n", "\n", " call = requests.get(endPoint)\n", " rawData = call.json()\n", "\n", " # Because randomizing race depends on life span\n", " waifuAge = self.getRandomAge()\n", " waifuRace = self.getRandomRace(waifuAge)\n", "\n", " waifuData:Dict[str:str] = {\n", " 'image': imagePath,\n", " 'name': rawData['name'],\n", " 'code_name': rawData['email_u'],\n", " 'age': waifuAge,\n", " 'race': waifuRace,\n", " 'current_location': rawData['address'].replace('\\n', ' '),\n", " 'birthday': rawData['birth_data'][5:],\n", " 'representative_color': rawData['color'],\n", " 'blood_type': rawData['blood'],\n", " }\n", "\n", " self._vbose('dictionary', waifuData)\n", "\n", " with open(profileDataPath, 'a+') as f:\n", " f.write(json.dumps(waifuData, indent=4, ensure_ascii=False))\n", " f.write('\\n\\n\\n')\n", "\n", "\n", "\n", " def _getRandomImages(self, filename:str) -> None:\n", " \"\"\"Getting waifu images from waifulabs\"\"\"\n", " if self.bigWaifu:\n", " waifu = waifulabs.GenerateWaifu().GenerateBigWaifu()\n", " else:\n", " waifu = waifulabs.GenerateWaifu()\n", "\n", " waifu.save(self.dataPath + filename)\n", " self._vbose('image', self.dataPath + filename)\n", "\n", "\n", " def generateProfiles(self) -> None:\n", " \"\"\"Generate full waifu profiles\"\"\"\n", "\n", " # Set up data directory the first run\n", " if not os.path.isdir(self.dataPath):\n", " os.mkdir(self.dataPath)\n", "\n", " for i in range(self.numberOfProfiles):\n", " self._vbose('text', f'ID: {i + 1}/{self.numberOfProfiles}\\n')\n", "\n", " if not self.noProfile:\n", " self._getRandomProfile(imagePath = self.dataPath + f\"waifu-{i + 1}.png\")\n", " if not self.noImage:\n", " self._getRandomImages(filename=f\"waifu-{i + 1}.png\")\n", "\n", " time.sleep(1) # try not to DOS Waifulab's servers" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "_AUAWw9EcRuq" }, "outputs": [], "source": [ "if autoRun:\n", " waifuGen = Waifus(verbosity=verbose)\n", " waifuGen.generateProfiles()\n", " if autoSave:\n", " waifuGen.getAllInfo()" ] } ], "metadata": { "colab": { "collapsed_sections": [], "name": "aWaifu.ipynb", "provenance": [] }, "kernelspec": { "display_name": "Python 3", "name": "python3" }, "language_info": { "name": "python" } }, "nbformat": 4, "nbformat_minor": 0 }