def user_dashboard(request): # Notifications # Rest one beacause is the upper limit inclusive notifs = Notification.find(user=request.user, limit=NOTIFS_IN_DASHBOARD-1) # Stats total_links = UserLink.objects.filter(user=request.user).count() total_achieves = UserAchievement.objects.filter(user=request.user).count() # Latest links links_aux = UserLink.objects.filter( user=request.user).order_by('-id')[:LINKS_IN_DASHBOARD] links = [ShortLink.find(token=i.token) for i in links_aux] # Latest achievements achievements = UserAchievement.objects.filter( user=request.user).order_by('-id')[:ACHIEV_IN_DASHBOARD] context = { "notifications": notifs, "links": links, "stats": { "Total Links": total_links, "Achievements": total_achieves, "Level": request.user.profile.level.level_number, "Points": request.user.profile.points, }, "achievements": achievements } return render_to_response('userprofile/dashboard.html', context, context_instance=RequestContext(request))
def forward(request, token): # get the forwarding Forward sl = ShortLink.find(token=token) if sl.disabled: raise Http404 # Click :) click_link(token, request.META) if not re.search("^https?://.+", sl.url): forward_url = "http://{0}".format(sl.url) else: forward_url = sl.url # Add the points to the user user_link = UserLink.objects.get(token=token) # If returns something then level upload then notification new_level = utils.incr_points(user_link.user, settings.POINTS_PER_CLICK) if new_level: # Send notifications notif = LevelNotification(level=new_level, user_id=user_link.user.id) #notif.send_push() # Push realtime notification notif.save() # save the notification for the dashboard return redirect(forward_url)
def details(request, token): clicks = list(Click.findall(token=token)) # Sort clicks.sort(key=lambda click: click.click_id) short_link = ShortLink.find(token=token) # Get data for the charts browsers = get_data_for_charts(clicks, "browser") browsers.append("Browsers") os = get_data_for_charts(clicks, "os") os.append("OS") country = get_data_for_charts(clicks, "location") country.append("Country") not_json_data = (browsers, os, country) #Serialize json_data = json.dumps(not_json_data) data = { 'shortlink': short_link, 'clicks': clicks, 'json_data': json_data } return render_to_response('simple/details.html', data, context_instance=RequestContext(request))
def test_enable_link(self): clicks = random.randrange(0, 100000) counter = random.randrange(0, 100000) url = "xlarrakoetxea.org" sl = ShortLink(counter=counter, url=url, clicks=clicks) sl.save() sl.disable() sl2 = ShortLink.find(token=sl.token) self.assertTrue(sl2.disabled) sl2.enable() sl2 = ShortLink.find(token=sl.token) self.assertFalse(sl2.disabled)
def test_create_new_token(self): counter = random.randrange(100000) url = "http://xlarrakoetxea{0}.org".format(random.randrange(100)) # Set the counter ShortLink.set_counter(counter) # Call the async task with celery result = tasks.create_token.delay(url) new_token = result.get() #Check if the returned token is ok self.assertEquals(utils.counter_to_token(counter + 1), new_token) self.assertTrue(result.successful()) # Check if the link is stored in the database correctly sl = ShortLink.find(url=url)[0] # creation_date is trap!! :P sl2 = ShortLink(counter=counter + 1, url=url, creation_date=sl.creation_date) # The host and title are set after the instance was created so we add sl2.host = sl.host sl2.title = sl.title self.assertEquals(sl2, sl)
def test_get_shortLinks_by_url(self): times = 10 counters = [random.randrange(0, 100000) for i in range(times)] url = "xlarrakoetxea.org" for i in counters: sl = ShortLink(counter=i, url=url) sl.save() sls = ShortLink.find(url=sl.url) self.assertEquals(len(counters), len(sls))
def test_get_shortLink_by_token(self): counter = random.randrange(0, 100000) url = "xlarrakoetxea.org" title = "My webpage" host = "xlarrakoetxea.org" sl = ShortLink(token=utils.counter_to_token(counter), url=url, title=title, host=host) sl.save() sl2 = ShortLink.find(token=sl.token) self.assertEquals(sl, sl2)
def test_get_shortLink_by_counter(self): counter = random.randrange(0, 100000) url = "xlarrakoetxea.org" title = "My webpage" host = "xlarrakoetxea.org" sl = ShortLink(counter=counter, url=url, title=title, host=host) sl.save() sl2 = ShortLink.find(counter=counter) self.assertEquals(sl, sl2)
def links_index(request): # get the page page = int(request.GET.get('page', 1)) # Get the total pages (rounding up, ex: 1.2 pages means 2 pages) total_pages = int(math.ceil( float(UserLink.objects.filter( user=request.user).count()) / LINK_PER_PAGE)) # If the page doesn't exists then 404 if page > total_pages and total_pages > 0: raise Http404 # Get the links offset = LINK_PER_PAGE * (page - 1) limit = offset + LINK_PER_PAGE links_aux = UserLink.objects.filter(user=request.user).order_by('-id')[offset:limit] links = [ShortLink.find(token=i.token) for i in links_aux] # Group by day grouped_links = [] temp = [] for i in links: creation_date = unix_to_datetime(i.creation_date) if len(temp) == 0: temp.append(i) else: previous_date = unix_to_datetime(temp[0].creation_date) if previous_date.year == creation_date.year and\ previous_date.month == creation_date.month and\ previous_date.day == creation_date.day: temp.append(i) else: grouped_links.append(temp) temp = [] # If no links don't add them if temp: grouped_links.append(temp) context = { "total_pages": total_pages, "actual_page": page, "links": grouped_links } return render_to_response('links/user_links.html', context, context_instance=RequestContext(request))
def from_json(cls, json_dict): # Avoid circular dependency of the signals from linkshortener.models import ShortLink # Maybe the link has been deleted, so we catch the exception try: short_link = ShortLink.find(token=json_dict["token"]) sl = ShortLinkNotification(short_link, user_id=json_dict["user_id"]) sl.date = json_dict["date"] return sl except ShortLinkNotFoundError: pass
def disable_link(request): if request.method == "POST": form = DisableLinkForm(data=request.POST) if form.is_valid(): data = form.cleaned_data link_token = data['token'] # Disable the token sl = ShortLink.find(token=link_token) if not sl.disabled: sl.disable() else: sl.enable() return redirect(reverse(links_info, args=[link_token]))
def delete_link(request): if request.method == "POST": form = DisableLinkForm(data=request.POST) if form.is_valid(): data = form.cleaned_data link_token = data['token'] # Delete the token ul = UserLink.objects.get(token=link_token) ul.delete() sl = ShortLink.find(token=link_token) sl.delete() return redirect(reverse(links_index)) else: return redirect(reverse(links_info, args=[link_token]))
def test_decr_clicks(self): clicks = random.randrange(0, 100000) counter = random.randrange(0, 100000) url = "xlarrakoetxea.org" sl = ShortLink(counter=counter, url=url, clicks=clicks) sl.save() #decrement result = ShortLink.decr_clicks(sl.token) #decrement manually the old one sl.clicks = sl.clicks - 1 #Find sls = ShortLink.find(token=sl.token) self.assertEquals(sl.clicks, sls.clicks) self.assertEquals(result, sls.clicks)
def test_save_shortLink_autofield(self): times = random.randrange(1, 100) url = "xlarrakoetxea.org" title = "My webpage" host = "xlarrakoetxea.org" # Set the shor link counter for i in range(times): ShortLink.incr_counter() # Save sl = ShortLink() sl.url = url sl.title = title sl.host = host sl.save() # Check the correct counter sl2 = ShortLink.find(counter=times + 1) self.assertEquals(sl, sl2)
def findall(cls, token): """Finds all the click instances of a given token. Returns a set of Click instances :param token: the token that is associated to the clicks """ if not token: raise ClickError("Not enought data to find a Click instance") # Get the max counters counter = 0 try: short_link = ShortLink.find(token=token) counter = short_link.clicks except ShortLinkNotFoundError: raise ClickNotFoundError("Shortlink doesnt exists, clicks neither") clicks = set() for i in range(1, counter + 1): clicks.add(Click.find(token, i)) return clicks
def links_info(request, token): sl = ShortLink.find(token=token) clicks = Click.findall(token) # get browsers: browsers = {} os = {} languages = {} countries = {} countries_map = {} # The countries map doesn't have unknown dates_tmp = {} dates = [] date_format = "Date({0}, {1}, {2})" for i in clicks: # Browsers try: browsers[i.browser] += 1 except KeyError: browsers[i.browser] = 1 # Operative Systems try: os[i.os] += 1 except KeyError: os[i.os] = 1 # Languages (Browser) try: languages[i.language] += 1 except KeyError: languages[i.language] = 1 # Countries try: countries[i.location] += 1 if i.location: countries_map[i.location] += 1 except KeyError: countries[i.location] = 1 if i.location: countries_map[i.location] = 1 # dates dt = unix_to_datetime(i.click_date) dt_str = date_format.format(dt.year, dt.month-1, dt.day) try: dates_tmp[dt_str] += 1 except KeyError: dates_tmp[dt_str] = 1 # Fill the dates until now now = datetime_now_utc() temp_date = unix_to_datetime(sl.creation_date) # If the date doesn't have enough days in between then create a new range # of dates with more days (For graph visualization) rel_delta = relativedelta(now, temp_date) if rel_delta.year == 0 and rel_delta.month == 0 and rel_delta.day < 5 or\ rel_delta.hours < 24: try: days = MINIMUN_DAYS_FOR_CHART-rel_delta.day except TypeError: days = MINIMUN_DAYS_FOR_CHART now = now + relativedelta(days=days) while (temp_date.day != now.day or temp_date.month != now.month or temp_date.year != now.year): dt_str = date_format.format(temp_date.year, temp_date.month-1, temp_date.day) try: dates.append((dt_str, dates_tmp[dt_str])) except KeyError: dates.append((dt_str, 0)) temp_date += relativedelta(days=1) # Change None for unknown for the countries try: countries[_("Unknown")] = countries[None] del countries[None] except KeyError: pass context = { 'browser_data': pie_chart_json_transform("Browsers", browsers), 'os_data': pie_chart_json_transform("Operative systems", os), 'languages_data': pie_chart_json_transform("Languages", languages), 'countries_data': pie_chart_json_transform("Countries", countries), 'countries_map_data': pie_chart_json_transform("Countries", countries_map), 'dates_data': single_linechart_json_transform_with_list("Clicks", "Days", dates), 'short_link': sl } return render_to_response('links/link_info.html', context, context_instance=RequestContext(request))