def FPMCTransfer(data, min_session_len=2, min_sessions=1, time_length=72): ''' min_session_len: > 2 min_sessions: >= 1, all ok. just keep the same as deepMove time_length: keep the same as deepMoveTransfer return:{ data_list: [ (uid, target, pre-position: list) ], n_user, loc_set } ''' # 直接硬切吧,不找 base 了 features = data['features'] loc_set = [] data_list = [] uid = 0 for feature in features: # uid = feature['properties']['uid'] # for the dataset's uid don't start from 0, so just count from 0. session = [] traj_data = feature['geometry']['coordinates'] if len(traj_data) == 0: continue base_time = parseTime(traj_data[0]['time'], traj_data[0]['time_format']) for index, node in enumerate(traj_data): loc_hash = encodeLoc(node['location']) loc_set.append(loc_hash) if index == 0: session.append(loc_hash) else: now_time = parseTime(node['time'], node['time_format']) time_off = calculateTimeOff(now_time, base_time) if time_off < time_length and time_off >= 0: session.append(loc_hash) else: session = np.unique(session).tolist() # TODO: 这里去重是否合适 if len(session) >= min_session_len: data_list.append((uid, session)) session = [] base_time = now_time session.append(loc_hash) uid += 1 print('start encode') print('loc size', len(loc_set)) encoder = LabelEncoder() encoder.fit(loc_set) loc_set = [i for i in range(len(encoder.classes_))] print('finish encode') verbose = 100 total = len(data_list) for i in range(len(data_list)): length = len(data_list[i][1]) loc_temp = encoder.transform(data_list[i][1]).tolist() data_list[i] = (data_list[i][0], loc_temp[-1], loc_temp) if i % verbose == 0: print('finish {}/{}'.format(i, total)) return {'data_list': data_list, 'n_user': uid, 'loc_set': loc_set}
def handleTime(self): text = self.getText() start = text.find('<<') end = text.find('>>') # make sure the order is << then >> hasTime = True if start == -1 or end == -1 or end - start <= 3: hasTime = False if hasTime: timeStr = text[start + 2:end].strip() parsedTime = utils.parseTime(timeStr) self.parsedTime = parsedTime # calculate time diff diffStr = utils.timeDiff(parsedTime, short=True) #print diffStr if not self.hasTime: self.hasTime = True #print "starting thread" self.watchTime() #self.canvas.itemconfig(self.labelIndex, text=diffStr) else: self.hasTime = False self.canvas.itemconfig(self.labelIndex, text="")
def do_quiet(self, args): '''禁言某人,参数为昵称和时间(默认单位秒)''' if len(args) != 2: self.msg.reply('请给出昵称和时间。') return else: try: n = utils.parseTime(args[1]) except ValueError: self.msg.reply('Sorry,我无法理解你说的时间。') return target = get_user_by_nick(args[0]) if target is None: self.msg.reply('Sorry,查无此人。') return target.black_before = datetime.datetime.now() + datetime.timedelta(seconds=n) target.put() self.msg.reply(u'OK,禁言 %s %s。' % (target.nick, utils.displayTime(n))) send_to_all_except((self.sender.jid, target.jid), (u'%s 已被禁言 %s。' % (target.nick, utils.displayTime(n))) \ .encode('utf-8')) xmpp.send_message(target.jid, u'你已被管理员禁言 %s。' % utils.displayTime(n)) log_admin(self.sender, BLACK % (target.nick, n))
def printBlog(xy, img: Image, today: datetime, blog, idx = 0): if not blog.get('data'): return x = xy[0] y = xy[1] draw = ImageDraw.Draw(img) date = utils.parseTime(blog['data'][idx]['publishDate']) title = str(blog['data'][idx]['title']) subtitle = str(blog['data'][idx]['subtitle']) twoline, title = linebreakString(draw, title) title = truncateString(draw, title, 370) _, subtitle = linebreakString(draw, subtitle, (3 if twoline else 4), font = rbtv_config.fontTiny) subtitle = truncateString(draw, subtitle, 370, font = rbtv_config.fontTiny) draw.rectangle((0, y, 600, y + 137), fill = 0) draw.text((x + 210, y + 5), title, font = rbtv_config.fontSmall, fill = 255) draw.text((x + 210, y + 5 + (60 if twoline else 30)), subtitle, font = rbtv_config.fontTiny, fill = 255) r = requests.get('https:' + str(blog['data'][idx]['thumbImage'][0]['url'])) preview = Image.open(BytesIO(r.content)) maxsize = (200, 140) tn_image = preview.thumbnail(maxsize) img.paste(preview, (x, y)) delta = getTimeDelta(int((today - date).total_seconds())) draw.text((x, y - 25), delta, font = rbtv_config.fontTiny, fill = 0)
def getCookingTime(htmlDocument): """ Parse BS Object and return dict of cooking time information. """ timeSpan = htmlDocument.find("span", class_="ready-in-time") hour, minute = utils.parseTime(timeSpan.next) timeInfo = { "hour": hour, "minute": minute } return timeInfo
def get_current_screen(self, img: Image, upcoming = False, detail = False) -> Image: #today = datetime.today().astimezone() #requires pyhton 3.6 today = datetime.today() data = self.api.getSchedule(today) draw = ImageDraw.Draw(img) self._draw_header(img, today) #print(utils.parseTime(data['data'][0]['date'])) shows = [] for i in range(len(data['data'])): for s in data['data'][i]['elements']: shows.append(s) print(len(shows)) pos = 0 hasCurrent = False cnt = 3 if detail else 6 for i in range(len(shows)): timeStart = utils.parseTime(shows[i]['timeStart']) timeEnd = utils.parseTime(shows[i]['timeEnd']) if timeEnd < today: continue if timeStart < today and timeEnd > today and not hasCurrent: print(shows[i]['title'], i) rbtv_printer.printCurrent(img, shows[i], timeStart, timeEnd, today, rbtv_config.fontSmall) hasCurrent = True # sometimes shows overlap a few minutes continue if not upcoming: break rbtv_printer.printUpcomming(img, shows[i], timeStart, pos, detail) pos += 1 if pos > cnt: break return img
def printNotification(xy, img: Image, today: datetime, data, idx: int, size: int): if not data.get('data'): return x = xy[0] y = xy[1] delta = (today - utils.parseTime(data['date'])).total_seconds() draw = ImageDraw.Draw(img) title = getTimeDelta(delta) + ' - ' + str(data['data']['show']) + ' / Abonniert: ' + str(data['data']['name']) draw.text((x, y), title, font = rbtv_config.fontTiny, fill = 0) yOffset = 25 draw.rectangle((0, y + yOffset, 600, y + yOffset + 140), fill = 0) try: f = None if isinstance(data['data']['thumbnail'], list): r = requests.get(data['data']['thumbnail'][0]['url']) else: r = requests.get(data['data']['thumbnail']) thumbnail = Image.open(BytesIO(r.content)) maxsize = (250, 140) tn_image = thumbnail.thumbnail(maxsize) img.paste(thumbnail, (x, y + yOffset)) except: print('could not thumbnail') pass _, title = linebreakString(draw, str(data['data']['title']), 5, 310) title = utils.string_normalizer(title) title = truncateString(draw, title, 310) draw.text((x + 255, y + yOffset), title, font = rbtv_config.fontSmall, fill = 255) number = str(idx) +'/'+ str(size) w,h = draw.textsize(number, font = rbtv_config.fontTiny) draw.text((rbtv_config.screen_width - w - 35, y), number, font = rbtv_config.fontTiny, fill = 0) draw.text((rbtv_config.screen_width - w - 2, y - 2), "", font = rbtv_config.fontAwesome) if data['status'] == 'unread': img.paste(rbtv_config.neu, (rbtv_config.screen_width - 2 - rbtv_config.neu.size[0], y + 162 - rbtv_config.neu.size[1]))
def do_snooze(self, args): '''暂停接收消息,参数为时间(默认单位为秒)。再次发送消息时自动清除''' if len(args) != 1: self.msg.reply('你想停止接收消息多久?') return else: try: n = utils.parseTime(args[0]) except ValueError: self.msg.reply('Sorry,我无法理解你说的时间。') return try: self.sender.snooze_before = datetime.datetime.now() + datetime.timedelta(seconds=n) except OverflowError: self.msg.reply('Sorry,你不能睡太久。') return self.sender.put() if n == 0: self.msg.reply('你已经醒来。') else: self.msg.reply(u'OK,停止接收消息 %s。' % utils.displayTime(n)) log_onoff(self.sender, SNOOZE % n)
async def tempmute(client, message): """ Mute la personne mentionnée pendant un certain temps. Prototype: "tempmute @user [@user ...] temps" Avec le temps "1h 1m 1s" Exemples: "tempmute @someone 1m" "tempmute @one @two 1h 1m 1s" """ msg_channel = message.channel author = message.author if msg_channel.permissions_for(author).manage_messages: time = utils.parseTime(message.content) overwrite = discord.PermissionOverwrite() overwrite.send_messages = False overwrite.speak = False output_msg = "" for member in message.mentions: output_msg += "{} ".format(member.mention) for channel in msg_channel.server.channels: await client.edit_channel_permissions(channel, member, overwrite) output_msg += "a été rendu muet pour {} secondes".format(time) await client.send_message(msg_channel, output_msg) await asyncio.sleep(time) for member in message.mentions: for channel in msg_channel.server.channels: await client.delete_channel_permissions(channel, member)
def handle(msg): if 'from' in msg and 'username' in msg['from']: logging.info('>request from user: '******'from']['username']) username = msg['from']['username'] if 'from' in msg and 'id' in msg['from']: currId = str(msg['from']['id']) logging.info('>id: ' + currId) # Check if user is authorized if not isAuthorized(currId): logging.error('>user ' + currId + ' not authorized!') return text = msg['text'] logging.info('>text: ' + text) if utils.isValidCommand(text): tipoPost = text.replace('/', '') logging.debug('>tipoPost: ' + tipoPost) logging.info('>command - currId: ' + currId) bot.sendMessage(currId, 'Invia il link') setSession(currId, 'scelta', text, '', tipoPost) return currentSession = getSession(currId) if currentSession.step == 'scelta' and utils.isLink(text): link = text logging.info('>link - currId: ' + currId) rand = os.urandom(10) idPost = int.from_bytes(rand, 'big') res = '' try: logging.debug('>begin download page') pageObj = requests.get(link) logging.debug('>end download page') #logging.debug(pageObj) page = pageObj.text logging.debug('>page: ' + page) res = utils.parsePage( page) # TODO: Parsa la pagina per ottenere i dati except Exception as e: logging.error('>Error in parsing page: ' + link + ' - currId: ' + currId) logging.error(e) bot.sendMessage(currId, 'Errore, invia un link valido') return logging.info('>res: ' + res) setSession(currId, 'link', idPost, link, currentSession.tipoPost) tipoPost = currentSession.tipoPost logging.debug('>tipoPost: ' + tipoPost) # TODO: Prendi i dati da res post = Post(idUtente=currId, idPost=idPost, conferma=False, orario='', link=link, nomeProdotto='mio prodotto', prezzoPieno='', prezzoAttuale='', sconto='', scontoPercentuale='', tipoPost=tipoPost, inviato=False) postList.append(post) postText = composePost(post) keyboard = utils.getResponseKeyboard(link) bot.sendMessage(currId, postText, reply_markup=keyboard, parse_mode='Markdown') bot.sendMessage(currId, 'Invia l\'orario di programmazione') return if currentSession.step == 'link': if utils.isTime(text): logging.info('>time - currId: ' + currId) setSession(currId, 'orario', currentSession.note, currentSession.link, currentSession.tipoPost) orario = utils.parseTime(text) post = getPost(currentSession.note) post.orario = orario minute = str(orario.minute) if len(minute) == 1: minute = '0' + minute bot.sendMessage( currId, 'Confermi la programmazione in data ' + orario.strftime("%d/%m/%y") + ' ' + str(orario.hour) + ':' + minute + ' ?') else: bot.sendMessage(currId, 'Orario errato. Riprova') return if currentSession.step == 'orario' and ( text.lower() == 's' or text.lower() == 'si'): #TODO: Modifica con un bottone logging.info('>confirm - currId: ' + currId) logging.debug('>idPost: ' + str(currentSession.note)) post = getPost(currentSession.note) post.conferma = True logging.info('>post: ' + str(post.idPost) + ' confirmed currId: ' + currId) telegram_channel = config['telegram_api']['telegram_channel'] #bot.sendMessage(telegram_channel, str(post.idPost)) bot.sendMessage(currId, 'Post programmato correttamente') setSession(currId, 'conferma', '', '', '') else: logging.error('>unable to get id from request')
def judge(message, qid, name, group): if message.strip()[:2].lower() != 'ns': # 如果开头不是ns那么一切免谈,无事发生 return ############## Main ################### command = message.strip()[2:].strip() # 把ns去掉后面开始分割这个指令 commandPart = command.split() # 按照空格进行分割,但是后续要看看是不是加入更多的防傻判断 servername = init.SERVER try: entrance = commandPart[0].strip() except: entrance = '' if entrance in keyNewTeam: try: # 尝试解析参数,如果出错说明输入参数有误 date = parseDate(commandPart[1].strip()) time = parseTime(commandPart[2].strip()) dungeon = commandPart[3].strip() comment = commandPart[4].strip() assert (date != -1) assert (time != -1) except: mirai.throwError(target=group, errCode=100) return try: # 尝试解析是否指定了黑名单 useBlackList = commandPart[5].strip() except: useBlackList = 0 leader = sql.hasLeader(qid) if leader == -1: msg = '权限错误,请先申请成为团长' else: res = sql.createNewTeam(date, time, dungeon, comment, leader, useBlackList) if res == -1: msg = '数据库错误!请联系管理员' else: msg = '开团成功,{},团队ID为{}, 集合时间{} {} {}'.format( dungeon, res, date, parseWeekday(date), time) mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT", needAT=True, ATQQ=qid) elif entrance in keyShowall: res = sql.getTeam() if not res: msg = '当前没有在开团队' mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT") return else: msg = '' for i in range(len(res)): g = res[i] msg += '{}. ID:{} {} {} {} {} {} \n'.format( str(i + 1), g['teamID'], g['leaderName'], g['dungeon'], g['startTime'], parseWeekday(g['startTime']), g['comment']) msg += '------------------- \n' mirai.sendGroupMessage(target=group, content="在开团队已经通过临时会话发给您了~如果没收到请加机器人好友", messageType="TEXT", needAT=True, ATQQ=qid) mirai.sendTempMessage(target=group, QQ=qid, content=msg, messageType="TEXT") elif entrance in keyQuery: try: teamNumber = int(commandPart[1].strip()) res = sql.getInfo(teamNumber) except: res = [] teamNumber = None if teamNumber is None or not res: msg = '输入的团队ID不存在' mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT") else: image = img.GetImg(teamNumber) if image == -1: msg = '此团队目前没有人报名' mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT") else: mirai.sendGroupMessage(target=group, content=image, messageType="Image") elif entrance in keyEnroll: msg = '' try: teamNumber = int(commandPart[1].strip()) except: msg += '缺少团队ID ' try: vocation = commandPart[2].strip() mental = sql.getMental(vocation) assert (mental != -1) # 检查心法是否存在 except: msg += '缺少角色心法或心法不存在 ' try: memberName = commandPart[3].strip() except: msg += '缺少角色名称 ' try: syana = int(commandPart[4].strip()) assert (syana == 1 or syana == 0) except: syana = 0 if msg == '': res = sql.addMember(teamNumber, qid, memberName, mental, syana) if res == 0: team = sql.getInfo(teamNumber) msg = '已成功报名 {} {}团长 {} {}-{}'.format(team['startTime'], team['leaderName'], team['dungeon'], vocation, memberName) elif res == -1: msg = '已经在此团队中' elif res == -3: msg = '团队不存在或已过期' else: msg = '数据库错误!请联系管理员' else: msg += '\n报团格式:ns报团 团队ID 心法 角色名\n双修心法请在报团命令最后额外加空格加1' mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT", needAT=True, ATQQ=qid) elif entrance in keyDisenroll: msg = '' try: teamNumber = int(commandPart[1].strip()) except: msg += '缺少团队ID' if msg == '': res = sql.delMember(teamNumber, qid) if res == 0: team = sql.getInfo(teamNumber) msg = '已成功取消报名 {} {}团长'.format(team['startTime'], team['leaderName']) elif res == -1: msg = '不在此团队中' elif res == -3: msg = '团队不存在或已过期' else: msg = '数据库错误!请联系管理员' mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT", needAT=True, ATQQ=qid) elif entrance in keyDeleteTeam: msg = '' try: teamNumber = int(commandPart[1].strip()) except: msg = '缺少团队ID' if msg == '': leader = sql.hasLeader(qid) if leader == -1: msg = '权限错误,请先申请成为团长' else: res = sql.delTeam(teamNumber, leader) if res == 0: msg = '团队{}已经取消'.format(teamNumber) elif res == -1: msg = '此团队不存在' elif res == -2: msg = '取消开团失败,没有该权限' else: msg = '数据库错误!请联系管理员' mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT", needAT=True, ATQQ=qid) elif entrance in keyMacro: msg = '' try: mental = sql.getMental(commandPart[1].strip()) assert (mental != -1) # 检查心法是否存在 except: msg += '缺少心法名称或心法不存在' mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT", needAT=True, ATQQ=qid) return if msg == '': try: with open(init.MACRO_PATH + str(mental), 'r') as f: lines = f.readlines() msg = ''.join(lines) except: msg = '心法文件错误!请联系管理员' mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT", needAT=True, ATQQ=qid) return mirai.sendGroupMessage(target=group, content='宏命令已经通过临时会话私发给您了,如果没收到请加机器人好友', messageType="TEXT", needAT=True, ATQQ=qid) mirai.sendTempMessage(target=group, QQ=qid, content=msg, messageType="TEXT") elif entrance in keyHelp: msg = '在线用户手册: \nhttps://www.nsrobot.life/userguide/' mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT") elif entrance in keyAuthor: msg = '致谢与授权说明: \nhttps://github.com/Hallows/nsRobot/blob/main/README.md' mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT") elif entrance in keyFormation: try: mentalName = str(commandPart[1].strip()) except: msg = '通用阵眼:田螺(会会+无视防御)\n常用外功阵眼:\n凌雪(攻会会) 鲸鱼(破无会) 剑纯(会会无)\n常用内功阵眼:\n莫问(攻会无) 大师(攻破无) 气纯(会会无) \n花间(回蓝破防) 毒经(破会会)' mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT") return mentalID = sql.getMental(mentalName=mentalName) if mentalID != -1: try: image = jx3api.getFormation(mentalID) mirai.sendGroupMessage(target=group, content=image, messageType="Image") return except: msg = '无法获得心法名称,请检查名称' mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT") elif entrance in keyDaily: if len(commandPart) > 1: servername = str(commandPart[1].strip()) msg = jx3api.getDaily(servername) if msg == 'error': mirai.sendGroupMessage(target=group, content='日常查询错误!请联系管理员', messageType="TEXT") else: mirai.sendGroupMessage(target=group, content=msg, messageType="Image") elif entrance in keyGold: if len(commandPart) > 1: servername = str(commandPart[1].strip()) msg = jx3api.getGold(servername) if msg == 'error': mirai.sendGroupMessage(target=group, content='金价查询错误!请联系管理员', messageType="TEXT") else: mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT") elif entrance in keyServer: if len(commandPart) > 1: servername = str(commandPart[1].strip()) msg = jx3api.getServer(servername) if msg == 'error': mirai.sendGroupMessage(target=group, content='服务器状态查询错误!请联系管理员', messageType="TEXT") elif msg == 'UncertainServer': mirai.sendGroupMessage(target=group, content='请输入正确的区服名!', messageType="TEXT") else: mirai.sendGroupMessage(target=group, content=msg, messageType="Image") elif entrance in keyMethod: name = '' if len(commandPart) > 1: name = str(commandPart[1].strip()) msg = jx3api.getMethod(name) if msg == 'error': mirai.sendGroupMessage(target=group, content='参数错误!或者联系管理员', messageType="TEXT") else: mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT") elif entrance in keyFlower: name = '' if len(commandPart) > 1: name = str(commandPart[1].strip()) if len(commandPart) > 2: servername = str(commandPart[2].strip()) if name == '': mirai.sendGroupMessage(target=group, content='查询口令请增加具体花类', messageType="TEXT") return msg = jx3api.getFlower(name, servername) if msg == 'error': mirai.sendGroupMessage(target=group, content='花价查询错误!请联系管理员', messageType="TEXT") else: mirai.sendGroupMessage(target=group, content=msg, messageType="Image") elif entrance in keyExam: subject = '' if len(commandPart) > 1: subject = str(commandPart[1].strip()) msg = jx3api.getExam(subject) if msg == 'error': mirai.sendGroupMessage(target=group, content='科举查询错误!请联系管理员', messageType="TEXT") else: mirai.sendGroupMessage(target=group, content=msg, messageType="Image") elif entrance in keyMedicine: if len(commandPart) == 0: msg = jx3api.GetMedicine() else: msg = jx3api.GetMedicine(commandPart[1].strip()) if msg == -1: mirai.sendGroupMessage(target=group, content="小药查询错误,请检查心法名称", messageType="TEXT") else: mirai.sendGroupMessage(target=group, content=msg, messageType="Image") elif entrance in keyBroadcast: try: teamID = commandPart[1].strip() broadMsg = commandPart[2].strip() except: mirai.throwError(target=group, errCode=100) return teamInfo = sql.getInfo(teamID=teamID) if teamInfo == []: mirai.sendGroupMessage(target=group, content="输入的团队ID不存在", messageType="TEXT") return leader = sql.hasLeader(qid) if leader == -1: mirai.sendGroupMessage(target=group, content="你还不是团长,请联系管理员", messageType="TEXT", needAT=True, ATQQ=qid) teamInfo = sql.getMember(teamID=teamID) if teamInfo == []: mirai.sendGroupMessage(target=group, content="此团队暂时无人报名", messageType="TEXT") return mirai.sendGroupMessage(target=group, content="信息开始私聊给指定团队,根据人数机器人可能无响应数分钟", messageType="TEXT") for key in teamInfo: QQ = key['QQNumber'] print('sending to {}'.format(QQ)) mirai.sendTempMessage(target=group, QQ=QQ, content=broadMsg, messageType="TEXT") Lib_Time.sleep(5) return elif entrance in keyApplyLeader: try: nickName = commandPart[1].strip() activeTime = commandPart[2].strip() except: mirai.throwError(target=group, errCode=100) return result = sql.newLeader(QQ=qid, nickName=nickName, activeTime=activeTime) if result['result'] == -1: msg = '你已经申请过了,你的团长ID是{},请等待审核'.format(result['id']) elif result['result'] == -2: msg = '你已经是团长了,别闹' else: msg = '申请成功!你的团长ID是{}请联系管理审批!'.format(result['id']) mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT", needAT=True, ATQQ=qid) elif entrance in keyAcceptLeader: try: leaderID = commandPart[1].strip() except: mirai.throwError(target=group, errCode=100) return if qid not in init.managerQQ: msg = '你不是管理员,无权批准,请检查init.py文件中的managerQQ字段确认管理员QQ号' mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT", needAT=True, ATQQ=qid) return result = sql.acceptLeader(leaderID=leaderID) if result == -1: msg = '团长ID不存在或已通过申请' else: msg = '批准成功!' mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT", needAT=True, ATQQ=qid) elif entrance in keyMyteam: try: res = sql.inTeam(qid) except: mirai.throwError(target=group, errCode=500) return if res: msg = '' for i in range(len(res)): g = res[i] msg += '{}. ID:{} 团长:{},{} {} {} {} \n'.format( str(i + 1), g['teamID'], g['leaderName'], g['dungeon'], g['startTime'], parseWeekday(g['startTime']), g['comment']) msg += '------------------- \n' print(msg) mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT", needAT=True, ATQQ=qid) return else: msg = '目前您未报名任何团队!' mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT", needAT=True, ATQQ=qid) return elif entrance in keyMyleader: try: teams = [] leaderID = sql.hasLeader(qid) if leaderID != -1: leadername = sql.getLeader(leaderID) teams = sql.getTeam() except: mirai.throwError(target=group, errCode=500) return myteams = [] if teams and leaderID != -1: for team in teams: if team['leaderName'] == leadername: myteams.append(team) if myteams: msg = "团长{},您当前的在开团队有:\n".format(leadername) for myteam in myteams: msg += "在{}的{},id为:{}\n".format(myteam['startTime'], myteam['dungeon'], myteam['teamID']) print(msg) mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT", needAT=True, ATQQ=qid) return else: msg = "团长{},您目前没有在开团队,——干点正事吧!{}!——".format( leadername, leadername) print(msg) mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT", needAT=True, ATQQ=qid) return elif leaderID == -1: msg = "别闹,你还不是团长" print(msg) mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT", needAT=True, ATQQ=qid) return else: msg = "当前没有在开团队" print(msg) mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT", needAT=True, ATQQ=qid) return else: msg = '未知指令,请通过 ns帮助 进行查看' mirai.sendGroupMessage(target=group, content=msg, messageType="TEXT", needAT=True, ATQQ=qid)
def acquireLock(request): # custom shitty auth auth = request.GET.get('auth', None) if auth != None: if auth != 'sabasheyleqalo': return HttpResponseRedirect(REDIRECT_URL) request.user = User.objects.get(username='******') if not request.user.is_authenticated: return HttpResponseRedirect('/login/steam/?next=/pizza/lock') lock = redis.get('pizzaLock') if lock is None: lock = {} else: lock = json.loads(lock) # forceLock prevents users from acquiring lock after current one expires # it can be set by pizza+ users, forceLock expires after 2 if request.user.groups.filter( name='Pizza+').exists() or request.user.is_superuser: lockTime = parseTime(lock['time']) expired = datetime.datetime.now() - lockTime > datetime.timedelta( hours=1) giveLock(None, request.user.username, force=True) if expired: # set time 1 hr back so pizza+ users can pass the lock check # and so lock doesn't instantly expire if previous lock # was more than 2 hours ago updateLock(time=str(datetime.datetime.now() - datetime.timedelta(hours=1))) return HttpResponseRedirect('/pizza') return HttpResponse( f'დარჩა {datetime.timedelta(hours=1) - (datetime.datetime.now() - lockTime)}' ) if not request.user.groups.filter(name='pizzaHourly').exists(): return HttpResponseRedirect(REDIRECT_URL) try: lockTime = parseTime(lock['time']) diff = datetime.datetime.now() - lockTime # don't allow users to buy access more than 3 times (per day) dailyPurchases = len( Pizza_Acquire_Log.objects.filter( user=request.user.username, time__gte=datetime.datetime.now() - datetime.timedelta(1))) if dailyPurchases > 2: return HttpResponse( f"<a href='{DISCORD_INVITE}'>დღიური ლიმიტი (3) ამოიწურა</a>") if (not request.user.groups.filter(name='Pizza+').exists() and request.user.username == lock['user'] and datetime.datetime.now() - lockTime < datetime.timedelta( hours=1, minutes=5)): return HttpResponse( f"<a href='{DISCORD_INVITE}'>ვადის გასვლიდან არ გასულა 5 წუთი</a>" ) except Exception as e: # if lock is null print(e) diff = datetime.timedelta(hours=1) if lock.get('forceLock', False): # if was acquired in advance less than 2 hours ago if diff < datetime.timedelta(hours=2): return HttpResponse('ადგილი უკვე დაკავებულია') # after 2 hours, timer "resets" every 15 minutes. # if premium users accessed site for last 15 minutes # don't let someone else acquire lock premiumUsers = User.objects.filter(groups__name='Pizza+') logs = Pizza_Log.objects.filter(time__gte=datetime.datetime.now() - datetime.timedelta(minutes=15), tier='pizza') for u in premiumUsers: if logs.filter(user=u.username).exists(): return HttpResponse('ადგილი უკვე დაკავებულია') elif diff < datetime.timedelta(hours=1): return HttpResponse('ადგილი უკვე დაკავებულია') if not giveLock(request.user, request.user.username): return HttpResponse('არასაკმარისი თანხა') if auth is None: return HttpResponseRedirect('/pizza') else: return HttpResponse('საღოლ ყლეო')
def pizza(request): lock = redis.get('pizzaLock') lockTime = None if (not request.user.groups.filter(name='Pizza').exists() and not request.user.groups.filter(name='Pizza+').exists() and not request.user.is_superuser): return HttpResponseRedirect(REDIRECT_URL) # check recorded ip. if not set, set it to current ip ip = GetUserIP(request) if request.user.ip != ip and not request.user.is_staff: return HttpResponse( f'თქვენი IP {ip} არ ემთხვევა {request.user.ip}-ს </br><a href=\'{DISCORD_INVITE}\' target=\'_blank\' style=\'color: red\'>Discord</a>' ) if lock is None: if request.user.groups.filter( name='Pizza+').exists() or request.user.is_superuser: return HttpResponseRedirect('/pizza/lock') raise Exception() avatar = request.GET.get('avatar', None) lock = json.loads(lock) ### LOCK CHECK # allow to reverse search avatars even without lock if avatar is None and not request.user.is_superuser: timePassed = datetime.datetime.now() - parseTime(lock['time']) lockTime = datetime.timedelta(hours=1) - timePassed expired = timePassed > datetime.timedelta(hours=1) if lock['user'] != request.user.username: # if user got to this point who isn't current user or pizza+ # that means he's previous user who shouldn't have pizza group anymore if not request.user.groups.filter(name='Pizza+').exists(): revokePizzaAccess(request.user) return HttpResponseRedirect('/pizza/lock') # only pizza+ users get to this point. # redirect if lock wasn't acquired in advance # or time of pizzahourly user hasn't expired if not lock['forceLock'] or not expired: return HttpResponseRedirect('/pizza/lock') else: # first request to pizza after expiring if expired: if not request.user.groups.filter(name='Pizza+').exists(): revokePizzaAccess(request.user) return HttpResponseRedirect('/pizza/lock') #### END OF LOCK CHECK limit = request.GET.get('limit', 30) # filter listings based on amount of avatars hitsLimit = request.GET.get( 'hits', 50) # if steamid data is present, don't show listings with 50+ hits start = request.GET.get('start', 0) # show listings starting from ID count = request.GET.get('count', 100) # amount of listings displayed on single page scan = request.GET.get( 'scan', True) != False # render online statuses of listings with the page showAll = request.GET.get( 'showAll', False) != False # include listings without identified avatar try: limit = int(limit) hitsLimit = int(hitsLimit) start = int(start) end = int(count) + start except: return HttpResponse('must be integer') if avatar is None: timeFrame = parseTime(lock['time']) # don't filter listings for pizza+ if request.user.groups.filter( name='Pizza+').exists() or request.user.is_superuser: if showAll: listings = Pizza.objects.using('pizza').filter( time__gte=timeFrame).order_by('-id')[start:end] else: listings = Pizza.objects.using('pizza').filter(~Q( avatar='')).order_by('-id')[start:end] else: listings = Pizza.objects.using('pizza').filter( ~Q(avatar=''), time__gte=timeFrame).order_by('-id')[start:end] else: listings = Pizza.objects.using('pizza').filter( avatar__contains=avatar).order_by('-id')[start:end] final = [] for l in listings: if l.removed: continue try: details = l.details.split('\r\n') updated = int(''.join(filter(str.isdigit, details[-1]))) if updated > hitsLimit: l.removed = True l.save() continue except: pass splitURL = urllib.parse.unquote(l.item).split('/') l.game = splitURL[5] l.name = splitURL[6] try: l.color = icons[l.name]['color'] l.icon = icons[l.name]['icon_url'] except: pass l.avatars = [] if len(l.avatar.split(';')[:-1]) > 30: l.removed = True l.save() continue else: for a in l.avatar.split(';')[:-1]: profiles = SteamTracker_User.objects.using( 'steamtracker').filter(avatar=a) try: ''' calling len() on queryset executes count() in sql, which takes too long in 600mil+ database couldn't find other way to check if list has 100 items without calling len or this ''' profiles[100] length = limit except: length = len(profiles) obj = types.SimpleNamespace() obj.avatar = a if length == 1: obj.steamboost = 'https://steamid.uk/profile/%s' % profiles[ 0].steam64id obj.steamid = profiles[0].steam64id elif length >= limit: continue else: obj.steamboost = 'https://steamboost.ge/extension/avatar-finder/' + a onlineCount = 0 privateCount = 0 if length < 100: if not scan: profilesToFetch = [] for s64id in [str(i.steam64id) for i in profiles]: if s64id not in apiCache: profilesToFetch.append(s64id) if len(profilesToFetch) == 0: # all profiles cached for u in [ apiCache[str(u.steam64id)] for u in profiles ]: if u.get('personastate', 0) != 0: onlineCount += 1 if u['communityvisibilitystate'] != 3: privateCount += 1 else: # profiles are not cached, fetch and cache them try: count = 0 while True: try: data = requests.get( 'https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key=%s&format=json&steamids=%s' % (API_KEY, ','.join(profilesToFetch) )).json() break except: count += 1 if count > 5: # to skip next for loop raise Exception("boo") for u in data['response']['players']: apiCache[u["steamid"]] = u if u.get('personastate', 0) != 0: onlineCount += 1 if u['communityvisibilitystate'] != 3: privateCount += 1 except: onlineCount = -1 privateCount = -1 obj.count = f"{onlineCount} online out of {length} | {privateCount} private" else: obj.count = f"steamboost ({length})" l.avatars.append(obj) final.append(l) Pizza_Log.objects.create(user=request.user.username, user_cookie=request.COOKIES.get( 'steam64id', None), ip=GetUserIP(request), time=datetime.datetime.now()) return render(request, 'pizza.html', { 'listings': final, 'lockTime': lockTime, 'steamDown': steamDown })
def deepMoveTransfer(data, min_session_len=5, min_sessions=2, time_length=72): ''' data: raw data which obey the trajectory data format min_session_len: the min number of nodes in a session min_sessions: the min number of sessions for a user time_length: use for cut raw trajectory into sessions (需为 12 的整数倍) output: { uid: { sessions: { session_id: [ [loc, tim], [loc, tim] ], .... }, 按照 time_length 的时间间隔将一个用户的 trace 划分成多段 session train: [0, 1, 2], test: [3, 4] 按照一定比例,划分 train 与 test 合集。目前暂定是后 25% 的 session 作为 test } } ''' base_zero = time_length > 12 # 只对以半天为间隔的做特殊处理 features = data['features'] # 因为 DeepMove 将对 loc 进行了 labelEncode 所以需要先获得 loc 的全集 loc_set = [] data_transformed = {} for feature in features: uid = feature['properties']['uid'] sessions = {} traj_data = feature['geometry']['coordinates'] session_id = 1 session = {'loc': [], 'tim': []} if len(traj_data) == 0: # TODO: shouldn't happen this, throw error ? continue start_time = parseTime(traj_data[0]['time'], traj_data[0]['time_format']) base_time = calculateBaseTime(start_time, base_zero) for index, node in enumerate(traj_data): loc_hash = encodeLoc(node['location']) loc_set.append(loc_hash) if index == 0: session['loc'].append(loc_hash) session['tim'].append( start_time.hour - base_time.hour) # time encode from 0 ~ time_length else: now_time = parseTime(node['time'], node['time_format']) time_off = calculateTimeOff(now_time, base_time) if time_off < time_length and time_off >= 0: # should not be 乱序 # stay in the same session session['loc'].append(loc_hash) session['tim'].append(time_off) else: if len(session['loc']) >= min_session_len: # session less than 2 point should be filtered, because this will cause target be empty # new session will be created sessions[str(session_id)] = session # clear session and add session_id session_id += 1 session = {'loc': [], 'tim': []} start_time = now_time base_time = calculateBaseTime(start_time, base_zero) session['loc'].append(loc_hash) session['tim'].append(start_time.hour - base_time.hour) if len(session['loc']) >= min_session_len: sessions[str(session_id)] = session else: session_id -= 1 # TODO: there will be some trouble with only one session user if len(sessions) >= min_sessions: data_transformed[str(uid)] = {} data_transformed[str(uid)]['sessions'] = sessions # 25% session will be test session split_num = math.ceil(session_id * 0.6) + 1 data_transformed[str(uid)]['train'] = [ str(i) for i in range(1, split_num) ] if split_num < session_id: data_transformed[str(uid)]['test'] = [ str(i) for i in range(split_num, session_id + 1) ] else: data_transformed[str(uid)]['test'] = [] # label encode print('start encode') print('loc size ', len(loc_set)) encoder = LabelEncoder() encoder.fit(loc_set) print('finish encode') # do loc labelEncoder verbose = 100 cnt = 0 total_len = len(data_transformed) for user in data_transformed.keys(): for session in data_transformed[user]['sessions'].keys(): temp = [] # TODO: any more effecient way to do this ? length = len(data_transformed[user]['sessions'][session]['tim']) loc_tmp = encoder.transform( data_transformed[user]['sessions'][session]['loc']).reshape( length, 1).astype(int) tim_tmp = np.array( data_transformed[user]['sessions'][session]['tim']).reshape( length, 1).astype(int) data_transformed[user]['sessions'][session] = np.hstack( (loc_tmp, tim_tmp)).tolist() cnt += 1 if cnt % verbose == 0: print('data encode finish: {}/{}'.format(cnt, total_len)) res = { 'data_neural': data_transformed, 'loc_size': encoder.classes_.shape[0], 'uid_size': len(data_transformed) } return res