def edit(u=None,cid=0): try: db = open_db() # Query comment from id comment = db.query(Comment).filter_by(id=cid).first() if comment is None: abort(404) if comment.user_id != u.id and u.is_admin == False: abort(403) if request.method == 'POST': body = request.form.get('body') if len(body) == 0: raise XaieconException(gettext('Body too short')) # Update comment db.query(Comment).filter_by(id=cid).update({ 'body':body, 'body_html':md(body)}) db.commit() db.close() cache.delete_memoized(view) return redirect(f'/comment/view/{cid}') else: db.close() return render_template('post/edit_comment.html',u=u,title='Edit comment',comment=comment) except XaieconException as e: return render_template('user_error.html',u=u,title = 'Whoops!',err=e)
def send_notification(msg: str, target_id: int): db = open_db() notification = Notification(body=msg, body_html=md(msg), user_id=target_id) db.add(notification) db.commit() db.close()
def send_everyone_notification(msg: str): db = open_db() users = db.query(User).all() for u in users: notification = Notification(body=msg, body_html=md(msg), user_id=u.id) db.add(notification) db.commit() db.close()
def send_admin_notification(msg: str): db = open_db() admins = db.query(User).filter_by(is_admin=True).all() for a in admins: notification = Notification(body=msg, body_html=md(msg), user_id=a.id) db.add(notification) db.commit() db.close()
def message_send(data=None, u=None): if data is None: return '', 400 if data['channel_id'] == 0: return '', 400 db = open_db() body_html = data['body'] body_html = md(body_html) # Obtain embeds soup = BeautifulSoup(body_html, 'html.parser') for a in soup.find_all('a'): try: if a.get('href', None) is None: continue # Append embed html embed = obtain_embed_url(a['href']) if embed is None: continue embed_html = f'<iframe width="560" height="315" src="{embed}" allowfullscreen frameborder=\'0\'></iframe>' body_html += embed_html except requests.exceptions.ConnectionError: pass except requests.exceptions.MissingSchema: pass print(body_html) # Create new message message = Message(body=data['body'], body_html=body_html, user_id=u.id, channel_id=data['channel_id']) db.add(message) db.commit() # Send everyone the message db.refresh(message) data = { 'time_utc': message.creation_date, 'username': u.username, 'uid': u.id, 'body': message.body_html, 'msg_id': message.id, 'channel_id': data['channel_id'] } emit('make_message', data, broadcast=True) db.close()
def write(u=None): db = open_db() try: if request.method == 'POST': body = request.form.get('body','') title = request.form.get('title') keywords = request.form.get('keywords') link = request.form.get('link','') bid = request.form.get('bid') category = int(request.values.get('category','0')) show_votes = strtobool(request.form.get('show_votes','False')) is_nsfw = strtobool(request.form.get('is_nsfw','False')) if len(title) > 255: raise XaieconException('Too long title') if len(body) > 16000: raise XaieconException('Too long body') category = db.query(Category).filter_by(id=category).first() if category is None: raise XaieconException('Not a valid category') board = db.query(Board).filter_by(id=bid).first() if board is None: raise XaieconException('Invalid board') bid = board.id if u.is_banned_from_board(bid) == True: raise XaieconException(f'You\'re banned from /b/{board.name}') is_link = False embed_html = '' if link != '': is_link = True embed = obtain_embed_url(link) if embed is not None: embed_html = f'<iframe width="560" height="315" src="{embed}" allowfullscreen frameborder=\'0\'></iframe>' if body == '' and is_link == False: raise XaieconException('Empty body') if title is None or title == '': raise XaieconException('Empty title') body_html = md(body) post = Post(keywords=keywords, title=title, body=body, link_url=link, is_link=is_link, user_id=u.id, is_nsfw=is_nsfw, downvote_count=0, upvote_count=0, total_vote_count=0, category_id=category.id, board_id=bid, embed_html=embed_html, body_html=body_html, show_votes=show_votes) file = request.files['image'] if file: try: # Build paths and filenames image_filename = secure_filename(f'{secrets.token_hex(12)}.jpeg') image_filepath = os.path.join('user_data',image_filename) thumb_filename = secure_filename(f'thumb_{image_filename}') thumb_filepath = os.path.join('user_data',thumb_filename) # Save full image file file.save(image_filepath) # Create thumbnail for image image = PIL.Image.open(image_filepath) image = image.convert('RGB') image.thumbnail((128,128)) image.save(thumb_filepath) post.image_file = image_filename post.thumb_file = thumb_filename post.is_image = True post.is_thumb = True except PIL.UnidentifiedImageError: pass else: post.is_image = False if is_link == True: img = obtain_post_thumb(link) if img is not None: thumb_filename = secure_filename(f'thumb_{secrets.token_hex(12)}.jpeg') thumb_filepath = os.path.join('user_data',thumb_filename) timg = img.convert('RGB') timg.resize((128,128)) timg.save(thumb_filepath) post.thumb_file = thumb_filename post.is_thumb = True db.add(post) db.commit() db.refresh(post) csam_thread = threading.Thread(target=csam_check_post, args=(u.id,post.id,)) csam_thread.start() notif_msg = f'# {post.title}\n\rBy [/u/{u.username}](/user/view/{u.id}) on [/b/{board.name}](/board/view/{board.id})\n\r{post.body}' # Alert boardmaster of the posts in the guild if board.user_id != u.id: send_notification(notif_msg,board.user_id) # Notify followers follows = db.query(UserFollow).filter_by(target_id=u.id,notify=True).all() for f in follows: if f.user_id != u.id: send_notification(notif_msg,f.user_id) ping = body.find('@everyone') if ping != -1 and u.is_admin == True: users = db.query(User).all() for us in users: if us.id != u.id: send_notification(notif_msg,us.id) ping = body.find('@here') if ping != -1 and u.mods(post.board_id): subs = db.query(BoardSub).filter_by(board_id=post.board_id).all() for s in subs: if s.user_id != u.id: send_notification(notif_msg,s.user_id) for m in re.finditer(r'([u][\/]|[@])([a-zA-Z0-9#][^ ,.;:\n\r\t<>\/\'])*\w+',body): m = m.group(0) try: name = re.split(r'([u][\/]|[@])',m)[2] tag = name.split('#') # direct mention if len(tag) > 1: uid = int(tag[1]) user = db.query(User).filter_by(id=uid).first() if user is None: raise IndexError send_notification(notif_msg,user.id) else: users = db.query(User).filter_by(username=name).all() if users is None: raise IndexError for user in users: send_notification(notif_msg,user.id) except IndexError: pass db.close() # Mess with everyone's feed cache.delete_memoized(list_posts) cache.delete_memoized(list_nuked) cache.delete_memoized(list_feed) return redirect(f'/post/view/{post.id}') else: board = db.query(Board).filter_by(is_banned=False).options(joinedload('user_info')).all() categories = db.query(Category).all() db.close() return render_template('post/write.html',u=u,title='New post',boards=board,categories=categories) except XaieconException as e: db.rollback() db.close() return render_template('user_error.html',u=u,title = 'Whoops!',err=e)
def edit(u=None,pid=0): db = open_db() try: post = db.query(Post).filter_by(id=pid).first() if post is None: abort(404) if u.id != post.user_id and u.is_admin == False: raise XaieconException('User is not authorized') if request.method == 'POST': body = request.form.get('body') title = request.form.get('title') keywords = request.form.get('keywords') link = request.form.get('link','') category = int(request.form.get('category','0')) is_nsfw = strtobool(request.form.get('is_nsfw','False')) if len(title) > 255: raise XaieconException('Too long title') category = db.query(Category).filter_by(id=category).first() if category is None: raise XaieconException('Not a valid category') is_link = False embed_html = '' if link != '': is_link = True embed = obtain_embed_url(link) if embed is not None: embed_html = f'<iframe width="560" height="315" src="{embed}" allowfullscreen frameborder=\'0\'></iframe>' if body == None or body == '': raise XaieconException('Empty body') if title == None or title == '': raise XaieconException('Empty title') body_html = '' # Remove old image try: if post.is_image == True: os.remove(os.path.join('user_data',post.image_file)) os.remove(os.path.join('user_data',post.thumb_file)) except FileNotFoundError: pass file = request.files['image'] if file: try: # Build paths and filenames image_filename = secure_filename(f'{secrets.token_hex(12)}.jpeg') image_filepath = os.path.join('user_data',image_filename) thumb_filename = secure_filename(f'thumb_{image_filename}') thumb_filepath = os.path.join('user_data',thumb_filename) # Save full image file file.save(image_filepath) # Create thumbnail for image image = PIL.Image.open(image_filepath) image = image.convert('RGB') image.resize((128,128)) image.save(thumb_filepath) db.query(Post).filter_by(id=pid).update({ 'image_file':image_filename, 'thumb_file':thumb_filename, 'is_image':True, 'is_thumb':True}) except PIL.UnidentifiedImageError: # Failure creating image! db.query(Post).filter_by(id=pid).update({ 'is_image':False, 'is_thumb':False}) else: db.query(Post).filter_by(id=pid).update({ 'is_image':False, 'is_thumb':False}) if is_link == True: img = obtain_post_thumb(link) if img is not None: thumb_filename = secure_filename(f'thumb_{secrets.token_hex(12)}.jpeg') thumb_filepath = os.path.join('user_data',thumb_filename) img = img.convert('RGB') img.thumbnail((128,128)) img.save(thumb_filepath) db.query(Post).filter_by(id=pid).update({ 'is_thumb':True, 'thumb_file':thumb_filename}) body_html = md(body) # Update post entry on database db.query(Post).filter_by(id=pid).update({ 'keywords':keywords, 'body':body, 'body_html':body_html, 'is_link':is_link, 'is_nsfw':is_nsfw, 'title':title, 'link_url':link, 'category_id':category.id, 'body_html':body_html, 'embed_html':embed_html}) db.commit() csam_thread = threading.Thread(target=csam_check_post, args=(u.id,post.id,)) csam_thread.start() db.close() cache.delete_memoized(view,pid=pid) cache.delete_memoized(list_posts) cache.delete_memoized(list_nuked) cache.delete_memoized(list_feed) return redirect(f'/post/view/{pid}') else: categories = db.query(Category).all() db.close() return render_template('post/edit.html',u=u,title='Edit',post=post,categories=categories) except XaieconException as e: db.rollback() db.close() return render_template('user_error.html',u=u,title = 'Whoops!',err=e)
def create(u=None,pid=0): try: db = open_db() body = request.form.get('body') if len(body) == 0: raise XaieconException('Body too short') # Post exists in first place? post = db.query(Post).filter_by(id=pid).options(joinedload('*')).first() if post is None: abort(404) # Add comment comment = Comment(body=body,body_html=md(body),user_id=u.id,post_id=pid) db.add(comment) # Increment number of comments db.query(Post).filter_by(id=pid).update({'number_comments':post.number_comments+1}) db.commit() notif_msg = f'Comment by [/u/{comment.user_info.username}](/user/view/{post.user_info.id}) on [/b/{post.board_info.name}](/board/view/{post.board_info.id}) in post ***{post.title}*** [View](/comment/view/{comment.id})\n\r{comment.body}' idlist = [] if post.user_id != u.id and post.user_id not in idlist: idlist.append(post.user_id) # Notify followers follows = db.query(UserFollow).filter_by(target_id=u.id,notify=True).all() for f in follows: if f.user_id != u.id and f.user_id not in idlist: idlist.append(f.user_id) # Notify post poster if post.user_id != u.id and post.user_id not in idlist: idlist.append(post.user_id) # Notify commenter if comment.user_id != u.id and comment.user_id not in idlist: idlist.append(comment.user_id) for id in idlist: send_notification(notif_msg,id) ping = body.find('@everyone') if ping != -1 and u.is_admin == True: users = db.query(User).all() for us in users: if us.id != u.id: send_notification(notif_msg,us.id) ping = body.find('@here') if ping != -1 and u.mods(post.board_id): subs = db.query(BoardSub).filter_by(board_id=post.board_id).all() for s in subs: if s.user_id != u.id: send_notification(notif_msg,s.user_id) for m in re.finditer(r'([u][\/]|[@])([a-zA-Z0-9#][^ ,.;:\n\r\t<>\/\'])*\w+',body): m = m.group(0) print(m) try: name = re.split(r'([u][\/]|[@])',m)[2] tag = name.split('#') # direct mention if len(tag) > 1: uid = int(tag[1]) user = db.query(User).filter_by(id=uid).first() if user is None: raise IndexError send_notification(notif_msg,user.id) else: users = db.query(User).filter_by(username=name).all() if users is None: raise IndexError for user in users: send_notification(notif_msg,user.id) except IndexError: pass db.close() cache.delete_memoized(view_p) cache.delete_memoized(list_posts) cache.delete_memoized(list_nuked) cache.delete_memoized(list_feed) return redirect(f'/post/view/{pid}') except XaieconException as e: return render_template('user_error.html',u=u,title = 'Whoops!',err=e)