#! /usr/bin/env python3 # Mirai Nikki Bot, a video frame posting bot for Pleroma # Copyright (C) 2022 Anon # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from collections import OrderedDict def setup_episode(profile_name, path, frames, _skip, _nsfw, output_name, message, message_nsfw): return { "profile_name": profile_name, "path": path, "frames": frames, "skip": _skip, "nsfw": _nsfw, "output_name": output_name, "message": (message,), "message_nsfw": (message_nsfw,), "render_script": "./render/render_mirai_nikki_script.sh" } # Client credentials: >>>NEVER GIVE THESE OUT TO ANYONE<<< # Use the create_app.py script and follow the prompts to generate your tokens. Once generated, copy & paste them below. settings_server = OrderedDict([ ("app_name", "generate from create_app.py"), ("api_base_url", "generate from create_app.py"), ("client_id", "generate from create_app.py"), ("client_secret", "generate from create_app.py"), ("access_token", "generate from create_app.py") ]) settings_reminder = "07/05/2023 01:39AM" # Encryption settings: When using encryption the bot will ask you for your password before logging into your instance. # Use create_app.py and follow the instructions. Select yes when it asks you if you want to encrypt your credentials. # Paste the output below and never change the values. # If you want to encrypt or re-encrypt settings_server you can use encryption.py (or just regenerate your tokens) settings_encrypt = { "encrypt": False, "salt": "", "keyfile": None } # Basic settings to configure Yandere Bot's behavior settings_behavior = { "visibility": "unlisted", "feature_set": "pleroma", "uploads_per_post": 1, "max_errors": 6, "retry_seconds": 15, "content_type": "text/plain", "content_newline": "\n", "post_image_link": False, "debug": False } # Time string formats settings_time = { "time_format": "%I:%M%p", "time_format_seconds": "%I:%M:%S%p", "date_format": "%m/%d/%Y", "long_date_format": "%m/%d/%Y %I:%M%p", "long_date_seconds_format": "%m/%d/%Y %I:%M:%S%p", "long_date_week": "%m/%d/%Y %I:%M%p, %A", "datetime": "%Y.%m.%d_%I.%M.%S%p" } # The final frame (in seconds) end_frame = { "fd_ep01": 25*60+20.019000000, "fd_ep02": 23*60+47.969000000, "fd_ep03": 25*60+33.866000000, "fd_ep04": 23*60+49.095000000, "fd_ep05": 23*60+47.969000000, "fd_ep06": 23*60+50.096000000, "fd_ep07": 23*60+49.095000000, "fd_ep08": 23*60+48.094000000, "fd_ep09": 25*60+09.675000000, "fd_ep10": 23*60+49.095000000, "fd_ep11": 23*60+47.969000000, "fd_ep12": 23*60+50.096000000, "fd_ep13": 23*60+49.095000000, "fd_ep14": 23*60+47.927000000, "fd_ep15": 24*60+58.164000000, "fd_ep16": 23*60+49.095000000, "fd_ep17": 25*60+02.551000000, "fd_ep18": 23*60+50.096000000, "fd_ep19": 25*60+33.199000000, "fd_ep20": 25*60+38.370000000, "fd_ep21": 25*60+53.052000000, "fd_ep22": 25*60+56.055000000, "fd_ep23": 25*60+24.482000000, "fd_ep24": 23*60+50.096000000, "fd_ep25": 23*60+49.261000000, "fd_ep26": 24*60+44.692000000, "ova": 30*60+00.174000000 } # Tuple of time ranges to skip (in seconds) skip = { "fd_ep01": ( (40.958, 134), # OP (656.99, 661.995), # Mid (1349.014, 1427.009), # ED (1504.003, end_frame["fd_ep01"]) # Credits ), "fd_ep02": ( (36.035000, 130.964), # OP (756.005, 761.01), # Mid (1238.988, 1328.911), # ED (1412.995, end_frame["fd_ep02"]) # Credits ), "fd_ep03": ( (67.025000, 161.995), # OP (601.976, 606.94), # Mid (1323.948, 1413.954), # ED (1517.766, end_frame["fd_ep03"]) # Credits ), "fd_ep04": ( (91.049000, 185.977), # OP (744.035, 749.04), # Mid (1242.032, 1331.956), # ED (1413.037, end_frame["fd_ep04"]) # Credits ), "fd_ep05": ( (33.033000, 128.21), # OP (741.991, 746.996), # Mid (1204.954, 1294.96), # ED (1412.995, end_frame["fd_ep05"]) # Credits ), "fd_ep06": ( (19.019000, 114.031), # OP (1005.046, 1010.009), # Mid (1178.094, 1268.017), # ED (1414.079, end_frame["fd_ep06"]) # Credits ), "fd_ep07": ( (76.035000, 171.004), # OP (619.994, 624.958), # Mid (1235.067, 1325.908), # ED (1412.995, end_frame["fd_ep07"]) # Credits ), "fd_ep08": ( (29.196, 125.083), # OP (705.121, 710.084), # Mid (1189.146, 1279.069), # ED (1412.62, end_frame["fd_ep08"]) # Credits ), "fd_ep09": ( (137.012, 232.023), # OP (743.117, 749.04), # Mid (1323.989, 1413.996), # ED (1493.617, end_frame["fd_ep09"]) # Credits ), "fd_ep10": ( (29.446, 125.042), # OP (612.07, 617.033), # Mid (1250.082, 1340.005), # ED (1413.078, end_frame["fd_ep10"]) # Credits ), "fd_ep11": ( (58.058, 152.986), # OP (734.984, 739.948), # Mid (1180.012, 1270.019), # ED (1412.995, end_frame["fd_ep11"]) # Credits ), "fd_ep12": ( (37.037, 131.965), # OP (560.018, 565.023), # Mid (1215.715, 1307.014), # ED (1414.038, end_frame["fd_ep12"]) # Credits ), "fd_ep13": ( (48.048, 142.976), # OP (615.115, 615.99), # Mid (1226.6, 1300.424), # ED (1412.995, end_frame["fd_ep13"]) # Credits ), "fd_ep14": ( (57.057, 151.985), # OP (504.963, 509.926), # Mid (1191.857, 1283.908), # ED (1399.106, end_frame["fd_ep14"]) # Credits ), "fd_ep15": ( (40.04, 135.01), # OP (606.981, 611.945), # Mid (1323.948, 1413.954), # ED (1482.064, end_frame["fd_ep15"]) # Credits ), "fd_ep16": ( (20.02, 115.032), # OP (530.03, 534.993), # Mid (1235.067, 1324.99), # ED (1413.078, end_frame["fd_ep16"]) # Credits ), "fd_ep17": ( (15.265, 20.229), # OP - Episode Name (407.032, 496.955), # OP (705.997, 710.96), # Mid (1320.82, 1412.995), # ED (1489.738, end_frame["fd_ep17"]) # Credits ), "fd_ep18": ( (19.019, 109.026), # OP (590.882, 601.976), # Mid (1247.788, 1340.965), # ED (1414.038, end_frame["fd_ep18"]) # Credits ), "fd_ep19": ( (107.065, 202.035), # OP (778.069, 783.116), # Mid (1319.026, 1413.037), # ED (1517.182, end_frame["fd_ep19"]) # Credits ), "fd_ep20": ( (93.051, 187.979), # OP (740.031, 744.994), # Mid (1322.988, 1412.995), # ED (1523.397, end_frame["fd_ep20"]) # Credits ), "fd_ep21": ( (106.064, 200.992), # OP (590.006, 594.969), # Mid (1323.989, 1413.996), # ED (1536.91, end_frame["fd_ep21"]) # Credits ), "fd_ep22": ( (44.878, 140.974), # OP (636.01, 640.974), # Mid (1322.947, 1412.953), # ED (1539.997, end_frame["fd_ep22"]) # Credits ), "fd_ep23": ( (58.058, 147.981), # OP (788.997, 793.96), # Mid (1322.988, 1412.995), # ED (1509.508, end_frame["fd_ep23"]) # Credits ), "fd_ep24": ( (182.683, 274.983), # OP (617.242, 622.997), # Mid (1179.303, 1269.226), # ED (1414.038, end_frame["fd_ep24"]) # Credits ), "fd_ep25": ( (21.021, 116.033), # OP (649.065, 654.028), # Mid (1218.092, 1308.098), # ED (1413.12, end_frame["fd_ep25"]) # Credits ), "fd_ep26": ( (55.055, 149.983), # OP (645.019, 649.983), # Mid (1305.012, 1397.396), # ED (1477.726, end_frame["fd_ep26"]) # Credits ), "ova": ( (179.012, 273.356), # OP (1700.073, end_frame["ova"]) # ED ) } # Tuple of time ranges to mark as sensative (in seconds) nsfw = { "fd_ep01": (tuple()), "fd_ep02": ( # Yuno locker room (252.669, 258.592), ), "fd_ep03": ( # Minane strips from cosplay after escaping the high school (373.248, 386.052), # Yuno loses swimming top (537.37, 539.456), (542.042, 543.918), (552.927, 554.929), (566.316, 569.861) ), "fd_ep04": ( # Omakata cult, Minane tits (853.311, 859.776), (865.782, 871.454), (873.289, 887.512), (995.578, 1000.666), (1021.812, 1023.272), (1097.388, 1100.308), (1107.732, 1119.327), (1128.753, 1140.514), (1147.021, 1152.61), (1161.41, 1164.372), (1218.217, 1222.304) ), "fd_ep05": ( # Tsubaki's rape (128.253, 135.218), (209, 220.721), (224.516, 238.238), # Minane's tits again (313.605, 323.365), (343.051, 347.013), (353.061, 359.776), (367.284, 368.41), # Tsubaki's rape (717.634, 721.012), (857.065, 861.819), # Tsubaki strips yuno (965.84, 967.925), (984.233, 985.943), (1033.449, 1035.159), (1035.535, 1037.119), (1039.455, 1041.874), (1045.92, 1050.883), (1073.322, 1077.41), (1086.21, 1089.63), (1097.972, 1101.267), (1102.602, 1106.022), (1122.455, 1124.415) ), "fd_ep06": ( # Yuno finds Yukki's porno stash (383.55, 386.052), (387.554, 389.681), (394.269, 394.477), (395.353, 396.313), # Yukki's baby pictures, just to be safe (615.74, 619.953), (623.623, 632.048), (633.758, 634.425), # Yuno shower (800.133, 803.303), (825.325, 832.415), (842.8, 845.47), (852.518, 856.481), (869.66, 876.209) ), "fd_ep07": ( # Yuno shower, almost electrocuted by Fifth (356.69, 367.576), (379.588, 380.714), (390.807, 392.142), (399.357, 404.029), (404.279, 407.991) ), "fd_ep08": ( # Yukki trips, exposes Hinata's panties (328.328, 333.875), (340.257, 346.346) ), "fd_ep09": (tuple()), "fd_ep10": ( # Minane and detective bathroom scene + changing into cosplay (391.224, 392.142), (434.976, 435.936), # Brief shot of detective grabbing Minane's breast (496.037, 496.621) ), "fd_ep11": ( # Yuno peeing at hospital (802.135, 802.719), (811.144, 815.231), ), "fd_ep12": (tuple()), "fd_ep13": ( # Hinata in spa (270.604, 271.438), (271.605, 286.453), (302.636, 314.856), (318.652, 322.072), (322.948, 330.038), (335.085, 345.22), # Yandere Yuno, captured Yuki (1222.93, 1226.559), # Omake - Hinata fan service (1305.429, 1311.727), (1313.229, 1327.827), (1332.873, 1336.919), (1337.336, 1341.757), # Omake - Mao fan service (1344.093, 1350.391), (1352.351, 1365.99), (1370.661, 1378.878), (1385.885, 1386.552), (1391.473, 1395.394), (1397.813, 1412.953) ), "fd_ep14": ( # Yandere Yuno naked feeding Yukki (34.701, 40.666), (42.209, 53.136), (186.019, 190.941), (192.901, 199.741), (235.944, 238.864), (241.908, 244.661), (248.999, 258.175), (265.97, 268.894), (270.061, 272.647), (352.31, 355.856), (369.494, 374.457), (405.447, 406.907), (431.681, 434.1), (545.754, 552.343), (587.712, 596.638), (598.598, 601.476), (610.777, 611.444), (619.953, 624.165), (643.852, 646.312), (691.149, 694.36), (698.907, 700.825), (714.631, 718.843), (722.847, 729.062), (773.398, 777.61), (786.911, 790.623), (800.758, 810.476), (815.523, 819.986), (837.211, 839.13), (867.95, 869.41), (873.331, 873.998), (886.26, 890.223), (912.286, 924.757), (938.062, 943.484), (943.985, 944.819), (947.488, 948.364), (949.073, 950.867), (952.034, 953.995), (959.542, 964.13), (969.427, 977.643), (981.439, 983.316), (1003.044, 1011.677), (1040.79, 1059.475), ), "fd_ep15": ( # Yukki flashback of slapping Yuno (231.606, 233.483), (241.283, 244.077), # Ai's bra (just going to censor the close-up) (766.557, 768.393), (769.686, 771.187) ), "fd_ep16": (tuple()), "fd_ep17": ( # Ai Rape (282.657, 285.744), (288.663, 290.665), (368.994, 391.975), # Omake - Marco's ass (1422.838, 1431.764) ), "fd_ep18": (tuple()), "fd_ep19": ( # Yuno changes into casual (410.285, 422.38), (427.01, 427.677), # Yuno panties (452.452, 453.37), (461.92, 465.674), (488.196, 491.658) ), "fd_ep20": ( # Minane showering (35.827, 39.414), (66.358, 79.371), # Minane and Nishijima's baby lol (386.845, 389.055) ), "fd_ep21": ( # Yuno fanservice after Bacchus towers (1105.021, 1113.571), (1117.533, 1123.247) ), "fd_ep22": (tuple()), "fd_ep23": ( # Yuno and Yuki come together (619.911, 623.873), (626.668, 634.384), (640.932, 645.895), (687.854, 700.867), (713.421, 726.392), (746.996, 748.581), (753.878, 757.09), (769.978, 771.02), (776.276, 785.576), (798.214, 800.591), (813.438, 815.189), (836.794, 838.254), (923.089, 933.558), (1310.226, 1314.021), (1316.816, 1319.777), # Yuno Omake (1422.796, 1433.015), (1451.2, 1461.919), (1466.715, 1474.682) ), "fd_ep24": ( (1.001, 5.005), (141.058, 144.519), (150.4, 152.611), (275.025, 277.235), (310.894, 318.36), (324.574, 325.575), (337.587, 351.476), (371.955, 391.308), (395.478, 398.94), (409.242, 414.581), (431.431, 433.725) ), "fd_ep25": ( # Ai sleeping (732.982, 736.611), # Yuno illusion world, Wakabe (930.972, 934.016), (940.064, 942.4), (942.984, 944.61) ), "fd_ep26": (tuple()), "ova": (tuple()) } # Regular episodes start_episode = 1 end_episode = 26 profile_name = "fd_ep{}" rsc_name = "./rsc/fd{}.mkv" screenshot_folder = "/tmp/Future_Diary_EP{}_${{frame}}.jpg" msg = "#Future_Diary #yandere" msg_nsfw = "#Future_Diary #yandere #nsfw" # Use a list comprehension and convert it to a tuple since # regular episodes are named in ascending order regular_episodes = tuple(( setup_episode( profile_name .format(i), rsc_name .format(i), end_frame [profile_name.format(i)], skip [profile_name.format(i)], nsfw [profile_name.format(i)], screenshot_folder .format(i), msg .format(i), msg_nsfw .format(i) ) for i in (str(x).zfill(2) for x in range(start_episode, end_episode + 1)) )) # Future diary OVA ova = setup_episode( "ova", "./rsc/ova.mkv", end_frame ["ova"], skip ["ova"], nsfw ["ova"], "/tmp/Future_Diary_Redial_${frame}.jpg", msg .format("ova"), msg_nsfw .format("ova") ) # The actual post setting (tuple) settings_post = regular_episodes + (ova,)