社區妹子強烈須要拉黑功能,結果剛上線,妹子就被拉黑了…這是個悲傷的故事…html
對於種種緣由不想再理會的人,能夠刪除私信時選擇拉黑。拉黑後,拉黑者取消關注對方,刪除私信,不在接收對方私信。被拉黑者收到系統消息提示被拉黑,若是是惡意、不良信息則超過必定次數被禁號
,可是保留被拉黑以前全部狀態,包括關注、私信,可是再次發送私信時提示私信被對方拒絕接收
,再次關注提示對方拒絕被你加關注
。惟一解除拉黑的手段,拉黑方再次關注對方則自動取消拉黑。前端
之因此保留狀態,是爲了儘可能減小用戶被拉黑的感知,可是又會收到系統提醒,相互矛盾。python
刪除私信時勾選拉黑:把對方加入本身blacklist列表中,統計數據,取消關注,刪除私信會話。json
進入主頁:返回拉黑數據,點擊關注時則根據是否被拉黑進行提示。(更優方式:點擊關注時後臺判斷是否被拉黑,拉黑則拒絕該請求,不然正常關注)網絡
被拉黑者發送私信:進入私信頁面返回拉黑數據,已被拉黑則發送消息時直接提示私信被對方拒絕接收
,若是中途被拉黑後臺會主動判斷blacklist而提示私信被對方拒絕接收
。(更優方式:開始不傳遞拉黑數據,發送私信時後臺判斷提示)session
上面也提到了更優辦法,其實能夠減小查詢次數,可是最終沒用,仍是考慮到體驗的問題,blacklist是使用kv存儲的,後臺查詢比客戶端請求快,kv費用消耗低。因此每次查詢數據附帶後傳到前端,絕大多數狀況用戶點擊就有提示,而不存在網絡延時。app
刪除私信時勾選拉黑ui
# kvdb設置統計user被拉黑數量 def set_blacklist_count(user): blackcount_key = "blackcount_%s" % user.user_id blackcount = kv.get_value(blackcount_key) if blackcount is None: kv.set_value(blackcount_key, 1) else: kv.set_value(blackcount_key, blackcount+1) # 拉黑次數超過必定次數則發送郵件提醒 if blackcount >= 5: print 'blacklist-email' # 建立一個假用戶 null_user = User() null_user.nickname = user.nickname null_user.email = user.user_id null_user.password = blackcount content = u"您在社區的帳戶信息以下:" to_email = ['xxx@xxx.com'] subject = u"xxx" html = render_template("login_info_email.html", user=null_user, content=content) sc_mail(to_email, subject, html) return 'sucesss'
# 添加user到to_user的黑名單list def add_to_blacklist(user, to_user): # 禁止拉黑系統帳號 if user.id == 1: return 'failed' key = 'blacklist_%s' % to_user.user_id blacklist = kv.get_list(key) # 名單爲空 if blacklist is None: blacklist = [] blacklist.append(user.user_id) kv.set_list(key, blacklist) # 追加list else: # 是否已經被拉黑 if str(user.user_id) in blacklist: return 0 else: blacklist.append(user.user_id) kv.set_list(key, blacklist) return 1
# 消息發送 @app.route('/message/<int:user_id>', methods=['GET', 'POST']) @login_required def message(user_id): ... # 刪除私信與拉黑處理 if request.form.get('delete'): # 無私信對話直接返回 if session is None: return 'error' # 選定拉黑名單 if int(request.form.get('blacklist')) == 1: # 添加到本身黑名單中 ret = add_to_blacklist(user, g.user) # 取消關注 unfollow(user_id) # 發送系統私信 sys_user = User.query.get(100) content = u"系統消息:你已經被拉黑!惡意使用且被拉黑超過限定次數的帳號將被禁用。" sys_msg(sys_user, user, content) content = u"系統消息:你已拉黑%s!惡意使用且被拉黑超過限定次數的帳號將被禁用。" % user.nickname sys_msg(sys_user, g.user, content) # 拉黑數據統計 if ret: set_blacklist_count(user) # 刪除與其私信 if g.user.id == session.from_id: session.from_delete_time = datetime.now() if g.user.id == session.to_id: session.to_delete_time = datetime.now() db.session.add(session) db.session.commit() return 'success' ... # 進入私信判斷是否在對方黑名單中 blacklist_key = 'blacklist_%s' % user_id blacklist = kv.get_list(blacklist_key) inBlacklist = 1 if (blacklist is not None and str(g.user.user_id) in blacklist) else 0 # 是不是系統帳號 isSystem = 1 if user.id == 100 else 0 return render_template("msg_content.html", title=u'私信', messages=messages, user=user, inBlacklist=inBlacklist, isSystem=isSystem)
被拉黑者發送私信編碼
... # 提交數據 if request.form.get('message'): # 判斷是否在blacklist中 key = 'blacklist_%s' % user_id blacklist = kv.get_list(key) print blacklist if blacklist is not None and str(g.user.user_id) in blacklist: return 'blacklist' ...
訪問主頁和取消拉黑url
# 在對方blacklist中則拒絕關注請求 blacklist_key = 'blacklist_%s' % user_id blacklist = kv.get_list(blacklist_key) if str(g.user.user_id) in blacklist: # flash(u'對方拒絕被你加好友!') return redirect(url_for('profile', user_id=user_id, list=1)) user = User.query.filter_by(user_id=user_id).first() if user: if g.user.is_following(user): return redirect(url_for('profile', user_id=user_id)) else: # 用戶是否在blacklist中 blacklist_key = 'blacklist_%s' % g.user.user_id blacklist = kv.get_list(blacklist_key) # 取消拉黑 if blacklist is not None and str(user_id) in blacklist: blacklist.remove(str(user_id)) kv.set_list(blacklist_key, blacklist) ...
kv存取部分
以前的圖牀——基於七牛JS-SDK和KVDB已經提到過,只是作了list的補充。
# -*- coding: utf-8 -*- __author__ = 'SkyWay' import sae import json import sae.kvdb class KvdbStorage(): # 初始化kvdb def __init__(self): self.kv = sae.kvdb.KVClient() # 獲取value def get_value(self, key): return self.kv.get(key) # 獲取dict_value def get(self, key): string_value = self.kv.get(key) if string_value is None: return None return decode_dict(string_value) # 設置value def set_value(self, key, value): self.kv.set(key, value) # 設置dict_value def set(self, key, dict_value): string_value = encode_dict(dict_value) self.kv.set(key, string_value) # 設置tuple_list def set_list(self, key, list_value): string_value = encode_list(list_value) self.kv.set(key, string_value) # 獲取list def get_list(self, key): string_value = self.kv.get(key) if string_value is None: return None return decode_list(string_value) # 批量獲取key def getkeys_by_prefix(self, prefix): return list(self.kv.getkeys_by_prefix(prefix, limit=100, marker=None)) # 刪除key def delete(self, key): self.kv.delete(key) # 編碼字典 def encode_dict(my_dict): return "\x1e".join("%s\x1f%s" % x for x in my_dict.iteritems()) # 解碼字典 def decode_dict(my_string): return dict(x.split("\x1f") for x in my_string.split("\x1e")) # 編碼list def encode_list(my_list): return "\x1e".join(str(x) for x in my_list) # 解碼list def decode_list(my_string): return list(my_string.split("\x1e"))
至於編碼、解碼爲何用\x1e
和\x1f
和爲何最終鏈接成字符串,可參考SAE在kvdb保存數據的格式比較:json、pickle、string
策略其實已經差很少,固然,其實還應該不容許拉黑者給被拉黑者發送私信,可是好像也沒什麼必要,再說吧;還有拉黑超過次數發送郵件提醒管理員,其實不太科學,拉黑並不表明有不良信息或操做,因此要二次審覈。之因此沒有作舉報,一個是減小對用戶的迷惑性,而且常常經過系統帳號和用戶發消息,用戶也能夠經過私信來進行舉報。
實現方式可能還有改進的地方,之後慢慢改進,好比加入私信的等級,用戶對系統帳號的反饋級別較高會郵件提醒,在我的主頁增長舉報項等等。
Night!