def command(self, user, channel, msg): if not msg: self.msg(channel, "Must provide a victim to check") return victim = self.factory.alias.resolve(" ".join(msg)) dt = datetime.datetime yield self.factory.refresh_shows() shows = [] for show in self.factory.shows.values(): blame = "" if not show["encoded"]: continue if not show["tl_status"]: blame = show["translator"] elif not show["ed_status"]: blame = show["editor"] elif not show["tm_status"]: blame = show["timer"] elif not show["ts_status"]: blame = show["typesetter"] elif not show["qc_status"]: blame = show["qc"] if self.factory.alias.resolve(blame) == victim: shows.append(show) if not shows: self.msg(channel, "{} is not stalling anything right now.".format(victim)) return parts = [] for show in shows: updated = dt.utcnow() - dt.utcfromtimestamp(show["updated"]) when = dt2ts(updated) parts.append("{} ({} ago)".format(show["series"], when)) self.msg(channel, "{} is stalling: {}".format(victim, ", ".join(parts)))
def command(self, user, channel, msg): permissions = self.getPermissions(user) now = datetime.datetime.utcnow() if "owner" in permissions: cooldown = datetime.timedelta(minutes=0) elif "admin" in permissions: cooldown = datetime.timedelta(minutes=0) elif user.lower() in self.admins: # Just for aers cooldown = datetime.timedelta(minutes=0) else: cooldown = datetime.timedelta(minutes=3) if user not in cooldowns: cooldowns[user] = { "time": now, "warnings": 0, "kicks": 0 } if cooldowns[user]["time"] > now: if cooldowns[user]["warnings"] >= 5 or cooldowns[user]["kicks"] >= 10: cooldowns[user]["warnings"] = 0 cooldowns[user]["kicks"] = 0 self.kickban(channel, user, "Markov command abuse") elif cooldowns[user]["warnings"] >= 3: cooldowns[user]["kicks"] += 1 self.kick(channel, user, "Markov command abuse") else: cooldowns[user]["warnings"] += 1 diff = dt2ts(cooldowns[user]["time"] - now) self.notice(user, "You just used this command, please wait {} before using it again.".format(diff)) return if not msg: cooldowns[user]["time"] = now + cooldown cooldowns[user]["warnings"] = 0 message = yield self.factory.markov.ramble() self.msg(channel, message) return name = self.factory.alias.resolve(msg[0]) if self.isAdmin(name) and user.lower() not in self.admins: cooldown *= 5 if "owner" not in permissions or name != "list": if name not in self.factory.markov.users: self.msg(channel, "No data on {}".format(msg[0])) return else: cooldowns[user]["time"] = now + cooldown cooldowns[user]["warnings"] = 0 seed = msg[1] if len(msg) > 1 else "" message = yield self.factory.markov.ramble(name, seed) self.msg(channel, message) return self.msg(channel, ", ".join(self.factory.markov.users.keys()))
def command(self, user, channel, msg): dt = datetime.datetime now = dt.utcnow() shows = [] ret = [] for show in self.factory.shows.itervalues(): if show["current_ep"] == show["total_eps"]: continue diff = dt.utcfromtimestamp(show["airtime"]) - now if diff.days == 0 or (show["id"] == 17 and diff.total_seconds() > 0): shows.append((diff,show["series"],show["channel"])) shows.sort(key=lambda s: s[0]) if not shows: self.msg(channel, "No shows airing in the next 24 hours") for s in shows: self.msg(channel, "%s will finish airing in %s on %s" % (s[1], dt2ts(s[0]), s[2]))
def command(self, user, channel, msg): dt = datetime.datetime show = self.factory.resolve(" ".join(msg), channel) if show is None: return data = yield self.factory.load("show",show["id"],"substatus") if "status" in data and not data["status"]: self.msg(channel, data["message"]) return data = data["results"] if data["position"] in ["encoder","translator"]: data["updated"] = show["airtime"] + 30*60 # Airtime + 30min, adjusts for completion of airing updated = dt.utcnow() - dt.utcfromtimestamp(data["updated"]) when = dt2ts(updated) if data["position"] == "completed" and data["value"] == "completed": self.msg(channel, "%s is completed as of %s ago." % (show["series"], when)) elif data["position"] == "DROPPED" and data["value"] == "DROPPED": self.msg(channel, "%s has been dropped at episode %s as of %s ago." % (show["series"], data["episode"], when)) else: self.msg(channel, "Episode %s of %s is at the %s, %s, as of %s ago." % (data["episode"], show["series"], data["position"], data["value"], when))
def command(self, user, channel, msg): if not msg: self.msg(channel, config["help"]) return subcommands = ("rip", "autorip", "list", "info", "config", "reload", "login", "delete") command = msg[0].lower() if command not in subcommands: self.msg(channel, "Available subcommands are: {}. Use .cr [subcommand] for their use".format(", ".join(subcommands))) return if command == "rip": if len(msg) < 5: self.msg(channel, ".cr rip [contents] [quality] [episode] [series] || Contents is subs, video or both. Quality is 360, 480, 720, or 1080. Series uses CR's naming") return contents, quality, episode, series = msg[1], msg[2], msg[3], " ".join(msg[4:]) success, series = self.factory.crunchy.resolve(series) if contents not in ("subs","video","both"): self.msg(channel, "Invalid content, must be subs, video or both") if quality not in ("360", "480", "720", "1080"): self.msg(channel, "Invalid quality, must be 360, 480, 720, or 1080") return try: episode = int(episode) except: self.msg(channel, "Invalid episode number, must be an integer") return if not success: self.msg(channel, series) return key = "{:02d}".format(episode) if key not in self.factory.crunchy.data["shows"][series]: self.msg(channel, "No data for that episode, try again when CR has added it") return show = self.factory.crunchy.data["shows"][series][key] subs = contents in ("subs", "both") video = contents in ("video", "both") success = yield self.factory.crunchy.rip(show, quality, video, subs, lambda x: self.notice(user, x)) self.msg(channel, "Ripping of {} {:02d} [{}p] was {}".format(series.encode("utf8"), episode, quality, "successful" if success else "unsuccessful")) elif command == "autorip": if len(msg) < 4: self.msg(channel, ".cr autorip [contents] [quality] [series] || Contents is subs, video or both. Quality is 360, 480, 720, or 1080. Series uses CR's naming") return contents, quality, series = msg[1], msg[2], " ".join(msg[3:]) success, series = self.factory.crunchy.resolve(series) if contents not in ("subs","video","both"): self.msg(channel, "Invalid content, must be subs, video or both") if quality not in ("360", "480", "720", "1080"): self.msg(channel, "Invalid quality, must be 360, 480, 720, or 1080") return if not success: self.msg(channel, series) return subs = contents in ("subs", "both") video = contents in ("video", "both") self.factory.crunchy.data["auto_downloads"][series] = { "quality": quality, "video": video, "subs": subs, "downloaded": sorted(self.factory.crunchy.data["shows"][series].keys()) } contents = spliceContents(video, subs) self.msg(channel, "Set {} to autorip {} at {}p. You won't really know if it works though. ┐( ̄ー ̄)┌".format(series.encode("utf8"), contents, quality)) elif command == "list": if len(msg) < 2: self.msg(channel, ".cr list series || .cr list episodes [series] || .cr list autodownloads || Either lists known series, or known episodes for a series. Series uses CR's naming") return subcommand = msg[1].lower() if subcommand == "series": self.msg(channel, ", ".join(sorted(self.factory.crunchy.data["shows"].keys()))) elif subcommand == "episodes": if len(msg) < 3: self.msg(channel, ".cr list episodes [series] || You forgot the series name, try again.") return series = " ".join(msg[2:]) success, series = self.factory.crunchy.resolve(series) if not success: self.msg(channel, series) return self.msg(channel, ", ".join(sorted(self.factory.crunchy.data["shows"][series].keys()))) elif subcommand == "autodownloads": data = self.factory.crunchy.data["auto_downloads"] self.msg(channel, ", ".join(["{} for {} at {}p".format(spliceContents(data[k]["video"], data[k]["subs"]), k.encode("utf8"), data[k]["quality"]) for k in sorted(data.keys())])) else: self.msg(channel, ".cr list series || .cr list episodes [series] || .cr list autodownloads || Those are your only three options, stop trying to be a special snowflake.") elif command == "info": if len(msg) < 3: self.msg(channel, ".cr info [episode] [series] || Gives you data on an episode. Series uses CR's naming") return episode, series = msg[1], " ".join(msg[2:]) success, series = self.factory.crunchy.resolve(series) try: episode = int(episode) except: self.msg(channel, "Invalid episode number, must be an integer") return if not success: self.msg(channel, series) return key = "{:02d}".format(episode) if key not in self.factory.crunchy.data["shows"][series]: self.msg(channel, "No data for that episode, try again when CR has added it") return data = self.factory.crunchy.data["shows"][series][key] now = datetime.datetime.utcnow() airtime = datetime.datetime.utcfromtimestamp(data["airtime"]) if now > airtime: airing = "aired {} ago".format(dt2ts(now - airtime)) else: airing = "airs in {}".format(dt2ts(airtime - now)) self.msg(channel, "{} {:02d}, \"{}\", {} with a duration of {}. CR ID = {}.".format(series.encode("utf8"), episode, data["title"], airing, data["duration"], data["media_id"])) elif command == "config": if len(msg) < 2: self.msg(channel, ".cr config save || .cr config load || Saves or loads the config file") return subcommand = msg[1].lower() if subcommand == "load": self.factory.crunchy.load() self.msg(channel, "CR config loaded") elif subcommand == "save": self.factory.crunchy.save() self.msg(channel, "CR config saved") else: self.msg(channel, ".cr config save || .cr config load || Is it really that hard?") elif command == "reload": self.notice(user, "Starting caching") yield self.factory.crunchy.cache() self.msg(channel, "Crunchyroll data reloaded") elif command == "login": yield self.factory.crunchy.login() self.msg(channel, "Logged in to Crunchyroll") elif command == "delete": if not "owner" in self.getPermissions(user): self.msg(channel, "Insufficient permissions. Only the owner can use this command") return if len(msg) < 3: self.msg(channel, ".cr delete [episode] [series] || Deletes an episode from the cache, Series uses CR's naming") return key, series = msg[1], " ".join(msg[2:]) success, series = self.factory.crunchy.resolve(series) try: key = "{:02d}".format(int(key)) except: self.notice(user, "Episode was not an integer, assuming it was the exact key.") if not success: self.msg(channel, series) return if key not in self.factory.crunchy.data["shows"][series]: self.msg(channel, "No data for that episode, try again when CR has added it") return del self.factory.crunchy.data["shows"][series][key] self.msg(channel, "{} #{} deleted from Crunchyroll cache".format(series.encode("utf8"), key)) else: self.msg(channel, "ERROR 634: How the f**k did this happen?")