def feedback_unread(session): """ this is just a count of # of unread feedbacks """ count = 0 for fb in SESSION.get_messages_received_list(session): if not fb.get("is_read"): count += 1 return count
def index(request): """ Render the messages template. """ messages = SESSION.get_messages_sent_list(request.session) feedbacks = SESSION.get_messages_received_list(request.session) # initially display the first 20 messages/feedback chronologically messages.sort(key=lambda r: r.createdAt, reverse=True) feedbacks.sort(key=lambda r: r.createdAt, reverse=True) # prepare our template context variables use in our messages template data = { 'messages_nav': True, 'messages': messages[:PAGINATION_THRESHOLD], 'feedback': feedbacks[:PAGINATION_THRESHOLD], 'pag_threshold': PAGINATION_THRESHOLD, 'pag_page': 1, 'sent_count': len(messages), 'feedback_count': len(feedbacks), 'tab_feedback': request.GET.get('tab_feedback'), } if SESSION.get_patronStore_count(request.session): data['has_patrons'] = True # inserting this success and error message into the template # should be done in a cleaner way - this was done by the first guy # I just didn't bother changing it. if request.GET.get("success"): data['success'] = request.GET.get("success") if request.GET.get("error"): data['error'] = request.GET.get("error") return render(request, 'manage/messages.djhtml', data)
def feedback_unread(session): """ this is just a count of # of unread feedbacks """ count = 0 for fb in SESSION.get_messages_received_list(session): if not fb.get("is_read"): count += 1 return count
def feedback(request, feedback_id): """ Renders the feedback template with the stores feedbacks. """ data = { 'messages_nav': True, 'feedback_id':feedback_id, "store_name":\ SESSION.get_store(request.session).get("store_name"), } # get from the messages_received_list in session cache messages_received_list = SESSION.get_messages_received_list(\ request.session) i_remove, feedback = 0, None for ind, m in enumerate(messages_received_list): if m.objectId == feedback_id: feedback = m i_remove = ind break if not feedback: # feedack not found - redirect to messages page with error message return redirect(reverse('messages_index')+ "?%s" %\ urllib.urlencode({'error': 'Feedback not found.', "tab_feedback":1})) if not feedback.is_read: # update the feedback's read if not yet read feedback.is_read = True feedback.update() # make sure that the message stored in the list is the updated 1 messages_received_list.pop(i_remove) messages_received_list.insert(i_remove, feedback) request.session['messages_received_list'] = messages_received_list # inserting this success and error message into the template # should be done in a cleaner way - this was done by the # first guy. I just didn't bother changing it. if request.GET.get("success"): data['success'] = request.GET.get("success") if request.GET.get("error"): data['error'] = request.GET.get("error") # there should only be at most 1 reply data['reply'] = feedback.get('reply') data['feedback'] = feedback return render(request, 'manage/feedback.djhtml', data)
def feedback_delete(request, feedback_id): """ Handles requests to delete the feedback with the given feedback_id. """ store = SESSION.get_store(request.session) # get the feedback from the messages_received_list in session cache messages_received_list = SESSION.get_messages_received_list(\ request.session) i_remove, feedback = 0, None for ind, m in enumerate(messages_received_list): if m.objectId == feedback_id: feedback = m i_remove = ind break if not feedback: # feedback not found - it may have been deleted return redirect(reverse('messages_index')+ "?%s" %\ urllib.urlencode({'error': 'Feedback not found.'})) # we don't actually delete the feedback object, # we just remove from the store's relation store.remove_relation("ReceivedMessages_", [feedback.objectId]) # remove it from the messages_received_list in session cache messages_received_list.pop(i_remove) request.session['messages_received_list'] =\ messages_received_list # notify other dashboards logged into the same store of this change comet_receive( store.objectId, { COMET_RECEIVE_KEY_NAME: COMET_RECEIVE_KEY, "deletedFeedback": Message(objectId=feedback.objectId).jsonify(), }) return redirect(reverse('messages_index')+ "?%s" %\ urllib.urlencode({'success':'Feedback has been deleted.', 'tab_feedback':1}))
def processCometReceivedDict(session, postDict): employees_pending_list =\ SESSION.get_employees_pending_list(session) employees_approved_list =\ SESSION.get_employees_approved_list(session) messages_received_list =\ SESSION.get_messages_received_list(session) redemptions_pending =\ SESSION.get_redemptions_pending(session) redemptions_past =\ SESSION.get_redemptions_past(session) ############################################################# # FEEDBACKS_UNREAD ################################## newFeedback = postDict.get('newFeedback') if newFeedback: messages_received_ids =\ [ fb.objectId for fb in messages_received_list ] m = Message(**newFeedback) if m.objectId not in messages_received_ids: messages_received_list.insert(0, m) session['messages_received_list'] =\ messages_received_list ############################################################# # FEEDBACK DELETED ################################## deletedFeedback = postDict.get("deletedFeedback") if deletedFeedback: fb = Message(**deletedFeedback) for i, mro in enumerate(messages_received_list): if fb.objectId == mro.objectId: messages_received_list.pop(i) break session['messages_received_list'] =\ messages_received_list ############################################################# # MESSAGE SENT ################################## # need to check if this new message is an original message # or a reply to a feedback (the message sent by the patron)! # also may increment the message count! newMessage = postDict.get("newMessage") if newMessage: messages_received_ids =\ [ fb.objectId for fb in messages_received_list ] messages_sent_list =\ SESSION.get_messages_sent_list(session) messages_sent_ids =\ [ msg.objectId for msg in messages_sent_list ] m = Message(**newMessage) if m.objectId not in messages_sent_ids and\ m.message_type != FEEDBACK: messages_sent_list.insert(0, m) if 'message_count' in session: session['message_count'] =\ int(session['message_count']) + 1 # update an existing feedback if m.objectId in messages_received_ids and\ m.message_type == FEEDBACK: for i, mrl in enumerate(messages_received_list): if mrl.objectId == m.objectId: messages_received_list.pop(i) messages_received_list.insert(i, m) break session['messages_received_list'] =\ messages_received_list session['messages_sent_list'] = messages_sent_list ############################################################# # EMPLOYEES_PENDING ################################## # must also check if employee is already approved! pendingEmployee = postDict.get("pendingEmployee") if pendingEmployee: employees_approved_ids =\ [ emp.objectId for emp in employees_approved_list ] employees_pending_ids =\ [ emp.objectId for emp in employees_pending_list ] e = Employee(**pendingEmployee) if e.objectId not in employees_pending_ids and\ e.objectId not in employees_approved_ids: employees_pending_list.insert(0, e) session['employees_pending_list'] =\ employees_pending_list ############################################################# # EMPLOYEES APPROVED (pending to approved) ################# approvedEmployee = postDict.get("approvedEmployee") if approvedEmployee: emp = Employee(**approvedEmployee) # first check if the employee is in the pending list # if not then check if it is already approved for i, emp_pending in\ enumerate(employees_pending_list): if emp.objectId == emp_pending.objectId: emp = employees_pending_list.pop(i) emp.status = APPROVED employees_approved_list.insert(0, emp) break session['employees_pending_list'] =\ employees_pending_list session['employees_approved_list'] =\ employees_approved_list ############################################################# # EMPLOYEES NEW (straight to approved) ################# newEmployee = postDict.get("newEmployee") if newEmployee: employees_approved_ids =\ [ emp.objectId for emp in employees_approved_list ] emp = Employee(**newEmployee) if emp.objectId not in employees_approved_ids: employees_approved_list.insert(0, emp) session['employees_approved_list'] =\ employees_approved_list ############################################################# # EMPLOYEES DELETED/DENIED/REJECTED (pending/approved to pop)! deletedEmployee = postDict.get("deletedEmployee") if deletedEmployee: emp = Employee(**deletedEmployee) # check in approved emps for i, cop in enumerate(employees_approved_list): if cop.objectId == emp.objectId: employees_approved_list.pop(i) break # check in pending emps for i, cop in enumerate(employees_pending_list): if cop.objectId == emp.objectId: employees_pending_list.pop(i) break session['employees_approved_list'] =\ employees_approved_list session['employees_pending_list'] =\ employees_pending_list ############################################################# # EMPLOYEE UPDATED PUNCHES updatedEmployeePunch = postDict.get("updatedEmployeePunch") if updatedEmployeePunch: u_emp = Employee(**updatedEmployeePunch) for emp in employees_approved_list: if u_emp.objectId == emp.objectId: emp.set("lifetime_punches", u_emp.lifetime_punches) break session['employees_approved_list'] =\ employees_approved_list ############################################################# # REDEMPTIONS PENDING ### Only added to cache if it has the store_location_id as ### active_store_location_id pendingRedemption = postDict.get("pendingRedemption") if pendingRedemption: rr = RedeemReward(**pendingRedemption) # store_location_id can be null for backwards compat if not rr.store_location_id or rr.store_location_id ==\ session.get('active_store_location_id'): redemptions_pending_ids =\ [ red.objectId for red in redemptions_pending ] redemptions_past_ids =\ [ red.objectId for red in redemptions_past ] # need to check here if the redemption is new because # the dashboard that validated it will also receive # the validated redemption back. if rr.objectId not in redemptions_past_ids and\ rr.objectId not in redemptions_pending_ids: redemptions_pending.insert(0, rr) session['redemptions_pending'] =\ redemptions_pending ############################################################# # REDEMPTIONS APPROVED (pending to history) # Save cpu by skipping those that do not have the same # store_location_id as active_store_location_id approvedRedemption = postDict.get("approvedRedemption") if approvedRedemption: redemp = RedeemReward(**approvedRedemption) # store_location_id can be null for backwards compat if not redemp.store_location_id or redemp.store_location_id ==\ session.get('active_store_location_id'): # check if redemp is still in pending for i, redem in enumerate(redemptions_pending): if redem.objectId == redemp.objectId: r = redemptions_pending.pop(i) r.is_redeemed = True r.updatedAt = redemp.updatedAt redemptions_past.insert(0, r) break # if not then check if it is in the history already # the above shouldn't happen! session['redemptions_pending'] =\ redemptions_pending session['redemptions_past'] =\ redemptions_past ############################################################# # REDEMPTIONS DELETED ############################## # remove from pending (should not be in history!) # Save cpu by skipping those that do not have the same # store_location_id as active_store_location_id deletedRedemption = postDict.get("deletedRedemption") if deletedRedemption: redemp = RedeemReward(**deletedRedemption) # store_location_id can be null for backwards compat if not redemp.store_location_id or redemp.store_location_id ==\ session.get('active_store_location_id'): # check if redemp is still in pending for i, redem in enumerate(redemptions_pending): if redem.objectId == redemp.objectId: redemptions_pending.pop(i) break session['redemptions_pending'] =\ redemptions_pending ############################################################# # STORE UPDATED ############################## updatedStore = postDict.get("updatedStore") if updatedStore: store = Store(**updatedStore) # have to add the image url manually store.thumbnail_image_url = updatedStore.get("thumbnail_image_url") store.cover_image_url = updatedStore.get("cover_image_url") # below here for backwards compat store.store_avatar_url = store.thumbnail_image_url session['store'] = store updatedStoreThumbnailName = postDict.get("updatedStoreThumbnailName") if updatedStoreThumbnailName: store = session['store'] store.thumbnail_image = updatedStoreThumbnailName store.thumbnail_image_url = postDict.get("updatedStoreThumbnailUrl") # below here for backwards compat store.store_avatar = store.thumbnail_image store.store_avatar_url = store.thumbnail_image_url session['store'] = store updatedStoreCoverName = postDict.get("updatedStoreCoverName") if updatedStoreCoverName: store = session['store'] store.cover_image = updatedStoreCoverName store.cover_image_url = postDict.get("updatedStoreCoverUrl") session['store'] = store # this is in the settings tab in the dashboard but the field # is in the Store class updatedPunchesFacebook_int =\ postDict.get("updatedPunchesFacebook_int") if updatedPunchesFacebook_int: store = session['store'] store.punches_facebook = int(updatedPunchesFacebook_int) session['store'] = store ############################################################# # STORE LOCATION UPDATED ############################## ### Note that this is also being used to insert new StoreLocations updatedStoreLocation = postDict.get("updatedStoreLocation") if updatedStoreLocation: store_location = StoreLocation(**updatedStoreLocation) session['store_locations'][store_location.objectId] =\ store_location try: # also update the store_timezone session['store_timezone'] =\ pytz.timezone(store_location.get('store_timezone')) except Exception: # assign a default timezone session['store_timezone'] =\ pytz.timezone(TIME_ZONE) ############################################################# # ACCOUNT UPDATED ############################## updatedAccount = postDict.get("updatedAccount") if updatedAccount: updatedAccountObject = Account(**updatedAccount) # need to make sure that these are the same accounts! if session['account'].objectId ==\ updatedAccountObject.objectId: session['account'] = updatedAccountObject ############################################################# # SUBSCRIPTION UPDATED ############################## updatedSubscription =\ postDict.get("updatedSubscription") if updatedSubscription: subscription = Subscription(**updatedSubscription) store = session["store"] store.set('subscription', subscription) store.set('Subscription', subscription.objectId) session['subscription'] = subscription session['store'] = store ############################################################# # SETTINGS UPDATED ############################## updatedSettings = postDict.get("updatedSettings") if updatedSettings: settings = Settings(**updatedSettings) store = session["store"] store.set('settings', settings) store.set("Settings", settings.objectId) session['settings'] = settings session['store'] = store ############################################################# # REWARDS NEW ############################## newReward = postDict.get("newReward") if newReward: store = session['store'] rewards = store.get("rewards") rewards_ids = [ r['reward_id'] for r in rewards ] if newReward['reward_id'] not in rewards_ids: rewards.append(newReward) store.rewards = rewards session['store'] = store ############################################################# # REWARDS UPDATED ############################## updatedReward = postDict.get('updatedReward') if updatedReward: store = session['store'] mod_rewards = store.get("rewards") for i, mreward in enumerate(mod_rewards): # [{"reward_name":"Free bottle of wine", # "description":"Must be under $25 in value", # "punches":10,"redemption_count":0,reward_id:0},] if updatedReward['reward_id']==mreward['reward_id']: if updatedReward.has_key("redemption_count"): mod_rewards[i]['redemption_count'] =\ updatedReward['redemption_count'] if updatedReward.has_key("reward_name"): mod_rewards[i]['reward_name'] =\ updatedReward['reward_name'] if updatedReward.has_key("punches"): mod_rewards[i]['punches'] =\ updatedReward['punches'] if updatedReward.has_key("description"): mod_rewards[i]['description'] =\ updatedReward['description'] break store.rewards = mod_rewards session['store'] = store ############################################################# # REWARDS DELETED ############################## deletedReward = postDict.get("deletedReward") if deletedReward: store = session['store'] rewards = store.get("rewards") rewards_ids = [ r['reward_id'] for r in rewards ] if deletedReward['reward_id'] in rewards_ids: for i, r in enumerate(rewards): if r['reward_id'] == deletedReward['reward_id']: rewards.pop(i) break store.rewards = rewards session['store'] = store ############################################################# # PATRONSTORE_COUNT ################################## patronStore_int = postDict.get('patronStore_int') if patronStore_int: patronStore_int = int(patronStore_int) session['patronStore_count'] = patronStore_int
def comet(session_copy): # used by more than 1 (note that it is ok to retrieve all of # the lists since they are all pointers - not the actual list! employees_pending_list_copy =\ SESSION.get_employees_pending_list(session_copy) employees_approved_list_copy =\ SESSION.get_employees_approved_list(session_copy) messages_received_list_copy =\ SESSION.get_messages_received_list(session_copy) redemptions_pending_copy =\ SESSION.get_redemptions_pending(session_copy) redemptions_past_copy =\ SESSION.get_redemptions_past(session_copy) # this is the latest session data session = SessionStore(request.session.session_key) employees_pending_list =\ SESSION.get_employees_pending_list(session) employees_approved_list =\ SESSION.get_employees_approved_list(session) messages_received_list =\ SESSION.get_messages_received_list(session) redemptions_pending =\ SESSION.get_redemptions_pending(session) redemptions_past =\ SESSION.get_redemptions_past(session) # put the diffs between session_copy and session here data = {} ############################################################# # FEEDBACKS_UNREAD ################################## fbs_unread_copy = [ fb.objectId for fb in\ messages_received_list_copy if not fb.is_read ] fbs_unread = [ fb.objectId for fb in\ messages_received_list if not fb.is_read ] # get the difference between the two feedbacks_unread =\ tuple(set(fbs_unread) - set(fbs_unread_copy)) if feedbacks_unread: fb_unread = [] messages_received_ids =\ [ fb.objectId for fb in messages_received_list ] for feedback_id in feedbacks_unread: for fb in messages_received_list: if fb.objectId == feedback_id: fb_unread.append(fb.jsonify()) break if len(fb_unread) > 0: fb_count = 0 for fb in messages_received_list: if not fb.get("is_read"): fb_count += 1 data['feedbacks_unread'] = fb_unread data['feedback_unread_count'] = fb_count ############################################################# # EMPLOYEES_PENDING ################################## # must also check if employee is already approved! emps_pending_copy = [ emp.objectId for emp in employees_pending_list_copy ] emps_pending = [emp.objectId for emp in employees_pending_list] employees_pending =\ tuple(set(emps_pending) - set(emps_pending_copy)) if employees_pending: pending = [] for emp_id in employees_pending: for emp in employees_pending_list: if emp.objectId == emp_id: pending.append(emp.jsonify()) break if len(pending) > 0: data['employees_pending_count'] =\ len(employees_pending_list) data['employees_pending'] = pending ############################################################# # EMPLOYEES APPROVED (pending to approved) ################# emps_approved_copy = [ emp.objectId for emp in\ employees_approved_list_copy] emps_approved = [ emp.objectId for emp in\ employees_approved_list] appr_emps =\ tuple(set(emps_approved) - set(emps_approved_copy)) if appr_emps: approved = [] for appr_emp_id in appr_emps: for emp in employees_approved_list: if emp.objectId == appr_emp_id: approved.append(emp.jsonify()) break if len(approved) > 0: data['employees_approved'] = approved data['employees_pending_count'] =\ len(employees_pending_list) ############################################################# # EMPLOYEES DELETED/DENIED/REJECTED (pending/approved to pop)! # need to compare approved and pending! emps_copy = emps_approved_copy[:] emps_copy.extend(emps_pending_copy) emps = emps_approved[:] emps.extend(emps_pending) # emps_copy has the same or more items that emps del_emps = tuple(set(emps_copy) - set(emps)) if del_emps: deleted = [] for demp_id in del_emps: if demp_id in emps_approved_copy: emps_list = employees_approved_list_copy else: emps_list = employees_pending_list_copy for emp in emps_list: if emp.objectId == demp_id: deleted.append(emp.jsonify()) break if len(deleted) > 0: data['employees_pending_count'] =\ len(employees_pending_list) data['employees_deleted'] = deleted ############################################################# # REDEMPTIONS PENDING reds_pending_copy = [ r.objectId for r in\ redemptions_pending_copy ] reds_pending = [r.objectId for r in redemptions_pending] reds = tuple(set(reds_pending) - set(reds_pending_copy)) if reds: redemps = [] for r_id in reds: for redemp in redemptions_pending: if redemp.objectId == r_id: redemps.append(redemp.jsonify()) break if len(redemps) > 0: data['redemption_pending_count'] =\ len(redemptions_pending) data['redemptions_pending'] = redemps ############################################################# # REDEMPTIONS APPROVED (pending to history) reds_past_copy = [ r.objectId for r in\ redemptions_past_copy ] reds_past = [r.objectId for r in redemptions_past] appr_redemps =\ tuple(set(reds_past) - set(reds_past_copy)) if appr_redemps: redemp_js = [] for red_id in appr_redemps: for redemp in redemptions_past: if redemp.objectId == red_id: redemp_js.append(redemp.jsonify()) break if len(redemp_js) > 0: data['redemption_pending_count'] =\ len(redemptions_pending) data['redemptions_approved'] = redemp_js ############################################################# # REDEMPTIONS DELETED ############################## # remove from pending (should not be in history!) reds_copy = reds_past_copy[:] reds_copy.extend(reds_pending_copy) reds = reds_past[:] reds.extend(reds_pending) # reds_copy has the same or more items that reds del_redemps = tuple(set(reds_copy) - set(reds)) if del_redemps: redemp_js = [] for red_id in del_redemps: reds_list = [] if red_id in reds_past_copy: reds_list = redemptions_past_copy elif red_id in reds_pending_copy: reds_list = redemptions_pending_copy for redemp in reds_list: if redemp.objectId == red_id: redemp_js.append(redemp.jsonify()) break if len(redemp_js) > 0: data['redemption_pending_count'] =\ len(redemptions_pending) data['redemptions_deleted'] = redemp_js ############################################################# # SETTINGS UPDATED ############################## settings_copy = session_copy.get("settings") settings = session.get("settings") if settings_copy.get("retailer_pin") !=\ settings.get("retailer_pin"): data['retailer_pin'] = settings.get("retailer_pin") ############################################################# # REWARDS UPDATED ############################## rewards_copy = session_copy.get("store").get("rewards") rewards_copy =\ { reward['reward_id']:reward for reward in rewards_copy } rewards = session.get("store").get("rewards") rewards = {reward['reward_id']: reward for reward in rewards} updated_rewards = [] for reward_id, rew_copy in rewards_copy.iteritems(): # Note that some rewards may have been deleted! rew = rewards.get(reward_id) if rew and rew_copy['redemption_count'] !=\ rew['redemption_count']: # only the redemtpion_count and reward_id are used # in the client side updated_rewards.append({ "reward_id": reward_id, "redemption_count": rew['redemption_count'], }) if updated_rewards: data['rewards'] = updated_rewards ############################################################# # PATRONSTORE_COUNT ################################## patronStore_count_copy = int(session_copy["patronStore_count"]) patronStore_count = int(session["patronStore_count"]) if patronStore_count_copy != patronStore_count: data['patronStore_count'] = patronStore_count ############################################################# # ACTIVE_STORE_LOCATION_ID ############################ if session['active_store_location_id'] !=\ session_copy['active_store_location_id']: data['active_store_location_id'] =\ session['active_store_location_id'] # IMPORTANT! The request.session is the same as the # SessionStore(session_key)! so we must use the # request.session because it is automatically saved at the end # of each request- thereby overriding/undoing any changes made # to the SessionStore(session_key) key! # need to check if we are still logged in session = SessionStore(request.session.session_key) if 'account' in session and SESSION_KEY in session: request.session.clear() request.session.update(session) else: flush(request.session) ############################################################ # Respond ########################################### try: return HttpResponse(json.dumps(data), content_type="application/json") except (IOError, socket.error) as e: # broken pipe/socket. thread.exit() # exit silently
def comet(session_copy): # used by more than 1 (note that it is ok to retrieve all of # the lists since they are all pointers - not the actual list! employees_pending_list_copy =\ SESSION.get_employees_pending_list(session_copy) employees_approved_list_copy =\ SESSION.get_employees_approved_list(session_copy) messages_received_list_copy =\ SESSION.get_messages_received_list(session_copy) redemptions_pending_copy =\ SESSION.get_redemptions_pending(session_copy) redemptions_past_copy =\ SESSION.get_redemptions_past(session_copy) # this is the latest session data session = SessionStore(request.session.session_key) employees_pending_list =\ SESSION.get_employees_pending_list(session) employees_approved_list =\ SESSION.get_employees_approved_list(session) messages_received_list =\ SESSION.get_messages_received_list(session) redemptions_pending =\ SESSION.get_redemptions_pending(session) redemptions_past =\ SESSION.get_redemptions_past(session) # put the diffs between session_copy and session here data = {} ############################################################# # FEEDBACKS_UNREAD ################################## fbs_unread_copy = [ fb.objectId for fb in\ messages_received_list_copy if not fb.is_read ] fbs_unread = [ fb.objectId for fb in\ messages_received_list if not fb.is_read ] # get the difference between the two feedbacks_unread =\ tuple(set(fbs_unread) - set(fbs_unread_copy)) if feedbacks_unread: fb_unread = [] messages_received_ids =\ [ fb.objectId for fb in messages_received_list ] for feedback_id in feedbacks_unread: for fb in messages_received_list: if fb.objectId == feedback_id: fb_unread.append(fb.jsonify()) break if len(fb_unread) > 0: fb_count = 0 for fb in messages_received_list: if not fb.get("is_read"): fb_count += 1 data['feedbacks_unread'] = fb_unread data['feedback_unread_count'] = fb_count ############################################################# # EMPLOYEES_PENDING ################################## # must also check if employee is already approved! emps_pending_copy = [ emp.objectId for emp in employees_pending_list_copy ] emps_pending = [ emp.objectId for emp in employees_pending_list ] employees_pending =\ tuple(set(emps_pending) - set(emps_pending_copy)) if employees_pending: pending = [] for emp_id in employees_pending: for emp in employees_pending_list: if emp.objectId == emp_id: pending.append(emp.jsonify()) break if len(pending) > 0: data['employees_pending_count'] =\ len(employees_pending_list) data['employees_pending'] = pending ############################################################# # EMPLOYEES APPROVED (pending to approved) ################# emps_approved_copy = [ emp.objectId for emp in\ employees_approved_list_copy] emps_approved = [ emp.objectId for emp in\ employees_approved_list] appr_emps =\ tuple(set(emps_approved) - set(emps_approved_copy)) if appr_emps: approved = [] for appr_emp_id in appr_emps: for emp in employees_approved_list: if emp.objectId == appr_emp_id: approved.append(emp.jsonify()) break if len(approved) > 0: data['employees_approved'] = approved data['employees_pending_count'] =\ len(employees_pending_list) ############################################################# # EMPLOYEES DELETED/DENIED/REJECTED (pending/approved to pop)! # need to compare approved and pending! emps_copy = emps_approved_copy[:] emps_copy.extend(emps_pending_copy) emps = emps_approved[:] emps.extend(emps_pending) # emps_copy has the same or more items that emps del_emps = tuple(set(emps_copy) - set(emps)) if del_emps: deleted = [] for demp_id in del_emps: if demp_id in emps_approved_copy: emps_list = employees_approved_list_copy else: emps_list = employees_pending_list_copy for emp in emps_list: if emp.objectId == demp_id: deleted.append(emp.jsonify()) break if len(deleted) > 0: data['employees_pending_count'] =\ len(employees_pending_list) data['employees_deleted'] = deleted ############################################################# # REDEMPTIONS PENDING reds_pending_copy = [ r.objectId for r in\ redemptions_pending_copy ] reds_pending = [ r.objectId for r in redemptions_pending ] reds = tuple(set(reds_pending) - set(reds_pending_copy)) if reds: redemps = [] for r_id in reds: for redemp in redemptions_pending: if redemp.objectId == r_id: redemps.append(redemp.jsonify()) break if len(redemps) > 0: data['redemption_pending_count'] =\ len(redemptions_pending) data['redemptions_pending'] = redemps ############################################################# # REDEMPTIONS APPROVED (pending to history) reds_past_copy = [ r.objectId for r in\ redemptions_past_copy ] reds_past = [ r.objectId for r in redemptions_past ] appr_redemps =\ tuple(set(reds_past) - set(reds_past_copy)) if appr_redemps: redemp_js = [] for red_id in appr_redemps: for redemp in redemptions_past: if redemp.objectId == red_id: redemp_js.append(redemp.jsonify()) break if len(redemp_js) > 0: data['redemption_pending_count'] =\ len(redemptions_pending) data['redemptions_approved'] = redemp_js ############################################################# # REDEMPTIONS DELETED ############################## # remove from pending (should not be in history!) reds_copy = reds_past_copy[:] reds_copy.extend(reds_pending_copy) reds = reds_past[:] reds.extend(reds_pending) # reds_copy has the same or more items that reds del_redemps = tuple(set(reds_copy) - set(reds)) if del_redemps: redemp_js = [] for red_id in del_redemps: reds_list = [] if red_id in reds_past_copy: reds_list = redemptions_past_copy elif red_id in reds_pending_copy: reds_list = redemptions_pending_copy for redemp in reds_list: if redemp.objectId == red_id: redemp_js.append(redemp.jsonify()) break if len(redemp_js) > 0: data['redemption_pending_count'] =\ len(redemptions_pending) data['redemptions_deleted'] = redemp_js ############################################################# # SETTINGS UPDATED ############################## settings_copy = session_copy.get("settings") settings = session.get("settings") if settings_copy.get("retailer_pin") !=\ settings.get("retailer_pin"): data['retailer_pin'] = settings.get("retailer_pin") ############################################################# # REWARDS UPDATED ############################## rewards_copy = session_copy.get("store").get("rewards") rewards_copy =\ { reward['reward_id']:reward for reward in rewards_copy } rewards = session.get("store").get("rewards") rewards = { reward['reward_id']:reward for reward in rewards } updated_rewards = [] for reward_id, rew_copy in rewards_copy.iteritems(): # Note that some rewards may have been deleted! rew = rewards.get(reward_id) if rew and rew_copy['redemption_count'] !=\ rew['redemption_count']: # only the redemtpion_count and reward_id are used # in the client side updated_rewards.append({ "reward_id": reward_id, "redemption_count": rew['redemption_count'], }) if updated_rewards: data['rewards'] = updated_rewards ############################################################# # PATRONSTORE_COUNT ################################## patronStore_count_copy =int(session_copy["patronStore_count"]) patronStore_count = int(session["patronStore_count"]) if patronStore_count_copy != patronStore_count: data['patronStore_count'] = patronStore_count ############################################################# # ACTIVE_STORE_LOCATION_ID ############################ if session['active_store_location_id'] !=\ session_copy['active_store_location_id']: data['active_store_location_id'] =\ session['active_store_location_id'] # IMPORTANT! The request.session is the same as the # SessionStore(session_key)! so we must use the # request.session because it is automatically saved at the end # of each request- thereby overriding/undoing any changes made # to the SessionStore(session_key) key! # need to check if we are still logged in session = SessionStore(request.session.session_key) if 'account' in session and SESSION_KEY in session: request.session.clear() request.session.update(session) else: flush(request.session) ############################################################ # Respond ########################################### try: return HttpResponse(json.dumps(data), content_type="application/json") except (IOError, socket.error) as e: # broken pipe/socket. thread.exit() # exit silently
def processCometReceivedDict(session, postDict): employees_pending_list =\ SESSION.get_employees_pending_list(session) employees_approved_list =\ SESSION.get_employees_approved_list(session) messages_received_list =\ SESSION.get_messages_received_list(session) redemptions_pending =\ SESSION.get_redemptions_pending(session) redemptions_past =\ SESSION.get_redemptions_past(session) ############################################################# # FEEDBACKS_UNREAD ################################## newFeedback = postDict.get('newFeedback') if newFeedback: messages_received_ids =\ [ fb.objectId for fb in messages_received_list ] m = Message(**newFeedback) if m.objectId not in messages_received_ids: messages_received_list.insert(0, m) session['messages_received_list'] =\ messages_received_list ############################################################# # FEEDBACK DELETED ################################## deletedFeedback = postDict.get("deletedFeedback") if deletedFeedback: fb = Message(**deletedFeedback) for i, mro in enumerate(messages_received_list): if fb.objectId == mro.objectId: messages_received_list.pop(i) break session['messages_received_list'] =\ messages_received_list ############################################################# # MESSAGE SENT ################################## # need to check if this new message is an original message # or a reply to a feedback (the message sent by the patron)! # also may increment the message count! newMessage = postDict.get("newMessage") if newMessage: messages_received_ids =\ [ fb.objectId for fb in messages_received_list ] messages_sent_list =\ SESSION.get_messages_sent_list(session) messages_sent_ids =\ [ msg.objectId for msg in messages_sent_list ] m = Message(**newMessage) if m.objectId not in messages_sent_ids and\ m.message_type != FEEDBACK: messages_sent_list.insert(0, m) if 'message_count' in session: session['message_count'] =\ int(session['message_count']) + 1 # update an existing feedback if m.objectId in messages_received_ids and\ m.message_type == FEEDBACK: for i, mrl in enumerate(messages_received_list): if mrl.objectId == m.objectId: messages_received_list.pop(i) messages_received_list.insert(i, m) break session['messages_received_list'] =\ messages_received_list session['messages_sent_list'] = messages_sent_list ############################################################# # EMPLOYEES_PENDING ################################## # must also check if employee is already approved! pendingEmployee = postDict.get("pendingEmployee") if pendingEmployee: employees_approved_ids =\ [ emp.objectId for emp in employees_approved_list ] employees_pending_ids =\ [ emp.objectId for emp in employees_pending_list ] e = Employee(**pendingEmployee) if e.objectId not in employees_pending_ids and\ e.objectId not in employees_approved_ids: employees_pending_list.insert(0, e) session['employees_pending_list'] =\ employees_pending_list ############################################################# # EMPLOYEES APPROVED (pending to approved) ################# approvedEmployee = postDict.get("approvedEmployee") if approvedEmployee: emp = Employee(**approvedEmployee) # first check if the employee is in the pending list # if not then check if it is already approved for i, emp_pending in\ enumerate(employees_pending_list): if emp.objectId == emp_pending.objectId: emp = employees_pending_list.pop(i) emp.status = APPROVED employees_approved_list.insert(0, emp) break session['employees_pending_list'] =\ employees_pending_list session['employees_approved_list'] =\ employees_approved_list ############################################################# # EMPLOYEES NEW (straight to approved) ################# newEmployee = postDict.get("newEmployee") if newEmployee: employees_approved_ids =\ [ emp.objectId for emp in employees_approved_list ] emp = Employee(**newEmployee) if emp.objectId not in employees_approved_ids: employees_approved_list.insert(0, emp) session['employees_approved_list'] =\ employees_approved_list ############################################################# # EMPLOYEES DELETED/DENIED/REJECTED (pending/approved to pop)! deletedEmployee = postDict.get("deletedEmployee") if deletedEmployee: emp = Employee(**deletedEmployee) # check in approved emps for i, cop in enumerate(employees_approved_list): if cop.objectId == emp.objectId: employees_approved_list.pop(i) break # check in pending emps for i, cop in enumerate(employees_pending_list): if cop.objectId == emp.objectId: employees_pending_list.pop(i) break session['employees_approved_list'] =\ employees_approved_list session['employees_pending_list'] =\ employees_pending_list ############################################################# # EMPLOYEE UPDATED PUNCHES updatedEmployeePunch = postDict.get("updatedEmployeePunch") if updatedEmployeePunch: u_emp = Employee(**updatedEmployeePunch) for emp in employees_approved_list: if u_emp.objectId == emp.objectId: emp.set("lifetime_punches", u_emp.lifetime_punches) break session['employees_approved_list'] =\ employees_approved_list ############################################################# # REDEMPTIONS PENDING ### Only added to cache if it has the store_location_id as ### active_store_location_id pendingRedemption = postDict.get("pendingRedemption") if pendingRedemption: rr = RedeemReward(**pendingRedemption) # store_location_id can be null for backwards compat if not rr.store_location_id or rr.store_location_id ==\ session.get('active_store_location_id'): redemptions_pending_ids =\ [ red.objectId for red in redemptions_pending ] redemptions_past_ids =\ [ red.objectId for red in redemptions_past ] # need to check here if the redemption is new because # the dashboard that validated it will also receive # the validated redemption back. if rr.objectId not in redemptions_past_ids and\ rr.objectId not in redemptions_pending_ids: redemptions_pending.insert(0, rr) session['redemptions_pending'] =\ redemptions_pending ############################################################# # REDEMPTIONS APPROVED (pending to history) # Save cpu by skipping those that do not have the same # store_location_id as active_store_location_id approvedRedemption = postDict.get("approvedRedemption") if approvedRedemption: redemp = RedeemReward(**approvedRedemption) # store_location_id can be null for backwards compat if not redemp.store_location_id or redemp.store_location_id ==\ session.get('active_store_location_id'): # check if redemp is still in pending for i, redem in enumerate(redemptions_pending): if redem.objectId == redemp.objectId: r = redemptions_pending.pop(i) r.is_redeemed = True r.updatedAt = redemp.updatedAt redemptions_past.insert(0, r) break # if not then check if it is in the history already # the above shouldn't happen! session['redemptions_pending'] =\ redemptions_pending session['redemptions_past'] =\ redemptions_past ############################################################# # REDEMPTIONS DELETED ############################## # remove from pending (should not be in history!) # Save cpu by skipping those that do not have the same # store_location_id as active_store_location_id deletedRedemption = postDict.get("deletedRedemption") if deletedRedemption: redemp = RedeemReward(**deletedRedemption) # store_location_id can be null for backwards compat if not redemp.store_location_id or redemp.store_location_id ==\ session.get('active_store_location_id'): # check if redemp is still in pending for i, redem in enumerate(redemptions_pending): if redem.objectId == redemp.objectId: redemptions_pending.pop(i) break session['redemptions_pending'] =\ redemptions_pending ############################################################# # STORE UPDATED ############################## updatedStore = postDict.get("updatedStore") if updatedStore: store = Store(**updatedStore) # have to add the image url manually store.thumbnail_image_url = updatedStore.get("thumbnail_image_url") store.cover_image_url = updatedStore.get("cover_image_url") # below here for backwards compat store.store_avatar_url = store.thumbnail_image_url session['store'] = store updatedStoreThumbnailName = postDict.get("updatedStoreThumbnailName") if updatedStoreThumbnailName: store = session['store'] store.thumbnail_image = updatedStoreThumbnailName store.thumbnail_image_url = postDict.get( "updatedStoreThumbnailUrl") # below here for backwards compat store.store_avatar = store.thumbnail_image store.store_avatar_url = store.thumbnail_image_url session['store'] = store updatedStoreCoverName = postDict.get("updatedStoreCoverName") if updatedStoreCoverName: store = session['store'] store.cover_image = updatedStoreCoverName store.cover_image_url = postDict.get("updatedStoreCoverUrl") session['store'] = store # this is in the settings tab in the dashboard but the field # is in the Store class updatedPunchesFacebook_int =\ postDict.get("updatedPunchesFacebook_int") if updatedPunchesFacebook_int: store = session['store'] store.punches_facebook = int(updatedPunchesFacebook_int) session['store'] = store ############################################################# # STORE LOCATION UPDATED ############################## ### Note that this is also being used to insert new StoreLocations updatedStoreLocation = postDict.get("updatedStoreLocation") if updatedStoreLocation: store_location = StoreLocation(**updatedStoreLocation) session['store_locations'][store_location.objectId] =\ store_location try: # also update the store_timezone session['store_timezone'] =\ pytz.timezone(store_location.get('store_timezone')) except Exception: # assign a default timezone session['store_timezone'] =\ pytz.timezone(TIME_ZONE) ############################################################# # ACCOUNT UPDATED ############################## updatedAccount = postDict.get("updatedAccount") if updatedAccount: updatedAccountObject = Account(**updatedAccount) # need to make sure that these are the same accounts! if session['account'].objectId ==\ updatedAccountObject.objectId: session['account'] = updatedAccountObject ############################################################# # SUBSCRIPTION UPDATED ############################## updatedSubscription =\ postDict.get("updatedSubscription") if updatedSubscription: subscription = Subscription(**updatedSubscription) store = session["store"] store.set('subscription', subscription) store.set('Subscription', subscription.objectId) session['subscription'] = subscription session['store'] = store ############################################################# # SETTINGS UPDATED ############################## updatedSettings = postDict.get("updatedSettings") if updatedSettings: settings = Settings(**updatedSettings) store = session["store"] store.set('settings', settings) store.set("Settings", settings.objectId) session['settings'] = settings session['store'] = store ############################################################# # REWARDS NEW ############################## newReward = postDict.get("newReward") if newReward: store = session['store'] rewards = store.get("rewards") rewards_ids = [r['reward_id'] for r in rewards] if newReward['reward_id'] not in rewards_ids: rewards.append(newReward) store.rewards = rewards session['store'] = store ############################################################# # REWARDS UPDATED ############################## updatedReward = postDict.get('updatedReward') if updatedReward: store = session['store'] mod_rewards = store.get("rewards") for i, mreward in enumerate(mod_rewards): # [{"reward_name":"Free bottle of wine", # "description":"Must be under $25 in value", # "punches":10,"redemption_count":0,reward_id:0},] if updatedReward['reward_id'] == mreward['reward_id']: if updatedReward.has_key("redemption_count"): mod_rewards[i]['redemption_count'] =\ updatedReward['redemption_count'] if updatedReward.has_key("reward_name"): mod_rewards[i]['reward_name'] =\ updatedReward['reward_name'] if updatedReward.has_key("punches"): mod_rewards[i]['punches'] =\ updatedReward['punches'] if updatedReward.has_key("description"): mod_rewards[i]['description'] =\ updatedReward['description'] break store.rewards = mod_rewards session['store'] = store ############################################################# # REWARDS DELETED ############################## deletedReward = postDict.get("deletedReward") if deletedReward: store = session['store'] rewards = store.get("rewards") rewards_ids = [r['reward_id'] for r in rewards] if deletedReward['reward_id'] in rewards_ids: for i, r in enumerate(rewards): if r['reward_id'] == deletedReward['reward_id']: rewards.pop(i) break store.rewards = rewards session['store'] = store ############################################################# # PATRONSTORE_COUNT ################################## patronStore_int = postDict.get('patronStore_int') if patronStore_int: patronStore_int = int(patronStore_int) session['patronStore_count'] = patronStore_int
def feedback_reply(request, feedback_id): """ Render the feedback reply template. """ account = request.session['account'] store = SESSION.get_store(request.session) # data to be passed in the templace context data = { 'messages_nav': True, 'from_address': store.get("store_name"), } # get from the messages_received_list in session cache messages_received_list = SESSION.get_messages_received_list(\ request.session) i_remove, feedback = 0, None for ind, m in enumerate(messages_received_list): if m.objectId == feedback_id: feedback = m i_remove = ind break if not feedback: # feedack not found - redirect to messages page with error message return redirect(reverse('messages_index')+ "?%s" %\ urllib.urlencode({'error': 'Feedback not found.'})) if request.method == 'POST': # user submitted reply form body = request.POST.get('body') if body is not None: # strip the body so that it doesn't have trailing or # leading whitespaces body = body.strip() else: body = "" data['body'] = body if len(body) == 0: # body cannot be empty data['error'] = 'Please enter a message.' elif len(body) > 750: # body cannot exceed 750 cahracters data['error'] = 'Body must be less than 750 characters.' elif feedback.get('Reply'): # double check if feedback already has a reply # should not go here unless it is a hacker return redirect(reverse('messages_index')+ "?%s" %\ urllib.urlencode({'error':\ 'Feedback has already been replied to.'})) else: # all valid - this method of validation is dirty and not # the way to do it in Django. Use a form instead. # I just got lazy here. # create the Parse Message object msg = Message.objects().create(message_type=\ FEEDBACK, sender_name=store.get('store_name'), store_id=store.objectId, body=body) # add the created reply to the store's sent messages relation store.add_relation("SentMessages_", [msg.objectId]) # set feedback Reply pointer to message and update it feedback.set('Reply', msg.objectId) feedback.update() # store the updated feedback messages_received_list.pop(i_remove) messages_received_list.insert(i_remove, feedback) request.session['messages_received_list'] =\ messages_received_list # save the session now! cloud_call may take a bit! request.session.save() # make the cloud call cloud_call( "retailer_message", { "store_id": store.objectId, "store_name": store.get('store_name'), "message_id": feedback.objectId, "filter": 'one', "patron_id": feedback.get('patron_id'), "feedback_reply_body": body, }) # notify other tabs/browsers logged into the same store # about the newly created message. comet_receive( store.objectId, { COMET_RECEIVE_KEY_NAME: COMET_RECEIVE_KEY, "newMessage": feedback.jsonify() }) # make sure we have the latest session to save! request.session.clear() request.session.update(SessionStore(request.session.session_key)) return redirect(reverse('feedback_details', args=(feedback.objectId,)) + "?%s" %\ urllib.urlencode({'success':'Reply has been sent.'})) else: # user navigated to this page if feedback.get("Reply"): # if the user manually tweaks the url, then s/he might be # able to reply to a feedback that already has a reply. return redirect(reverse('feedback_details', args=(feedback.objectId,)) + "?%s" %\ urllib.urlencode({'error':'Cannot reply more than once.'})) # update store session cache request.session['store'] = store data['feedback'] = feedback # store the updated feedback messages_received_list.pop(i_remove) messages_received_list.insert(i_remove, feedback) request.session['messages_received_list'] =\ messages_received_list return render(request, 'manage/feedback_reply.djhtml', data)
def get_page(request): """ Returns the corresponding chunk of rows in html to plug into the sent/feedback table. """ if request.method == "GET": type = request.GET.get("type") page = int(request.GET.get("page")) - 1 if type == "sent": # we will be rendering the message chunk template template = "manage/message_chunk.djhtml" # retrieve the messages sent from our session cache messages = SESSION.get_messages_sent_list(request.session) # our input is called "date" which translates to "createdAt" header_map = {"date": "createdAt"} header = request.GET.get("header") # header can only be date at the moment if header: # sort the messages based on given order reverse = request.GET.get("order") == "desc" messages.sort(key=lambda r:\ r.__dict__[header_map[header]], reverse=reverse) # insert the messages chunk in the template data start = page * PAGINATION_THRESHOLD end = start + PAGINATION_THRESHOLD data = {"messages": messages[start:end]} # save our reordered messages request.session["messages_sent_list"] = messages elif type == "feedback": # we will be rendering the feedback chunk template template = "manage/feedback_chunk.djhtml" # retrieve the feedbacks from our session cache. feedbacks = SESSION.get_messages_received_list(request.session) # our inputs can be "feedback-date" mapping to "createdAt" # or "feedback-from" mapping to "sender_name" header_map = { "feedback-date": "createdAt", "feedback-from": "sender_name", } header = request.GET.get("header") if header: # sort the feedbacks based on the attribute and order reverse = request.GET.get("order") == "desc" feedbacks.sort(key=lambda r:\ r.__dict__[header_map[header]], reverse=reverse) # insert the feedbacks chunk in the template data start = page * PAGINATION_THRESHOLD end = start + PAGINATION_THRESHOLD data = {"feedback": feedbacks[start:end]} # save our reordered feedbacks request.session["messages_received_list"] = feedbacks # render our template with the feedback/messages sent chunks return render(request, template, data) # only GET methods are accepted here return HttpResponse("Bad request")