Add page for users to see their account's IP history.

This commit is contained in:
Neil Williams
2011-09-09 16:20:08 -07:00
parent 6650b02e00
commit e76d96d5b4
7 changed files with 134 additions and 1 deletions

View File

@@ -47,6 +47,7 @@ def make_map(global_conf={}, app_conf={}):
mc('/sup', controller='front', action='sup')
mc('/traffic', controller='front', action='site_traffic')
mc('/account-activity', controller='front', action='account_activity')
mc('/about/message/:where', controller='message', action='listing')
mc('/about/:location', controller='front',

View File

@@ -786,6 +786,11 @@ class FrontController(RedditController):
return BoringPage("traffic",
content = RedditTraffic()).render()
@validate(VUser())
def GET_account_activity(self):
return AccountActivityPage().render()
class FormsController(RedditController):
def GET_password(self):
@@ -1096,4 +1101,3 @@ class FormsController(RedditController):
giftmessage, passthrough)
).render()

View File

@@ -57,6 +57,14 @@ import graph, pycountry, time
from itertools import chain
from urllib import quote
# the ip tracking code is currently deeply tied with spam prevention stuff
# this will be open sourced as soon as it can be decoupled
try:
from r2admin.lib.ip_events import ips_by_account_id
except ImportError:
def ips_by_account_id(account_id):
return []
from things import wrap_links, default_thing_wrapper
datefmt = _force_utf8(_('%d %b %Y'))
@@ -284,6 +292,10 @@ class Reddit(Templated):
ps.append(SideContentBox(_("Recently viewed links"),
[ClickGadget(c.recent_clicks)]))
if c.user_is_loggedin:
activity_link = AccountActivityBox()
ps.append(activity_link)
return ps
def render(self, *a, **kw):
@@ -370,6 +382,10 @@ class Reddit(Templated):
"""returns a Wrapped (or renderable) item for the main content div."""
return self.content_stack((self.infobar, self.nav_menu, self._content))
class AccountActivityBox(Templated):
def __init__(self):
super(AccountActivityBox, self).__init__()
class RedditHeader(Templated):
def __init__(self):
pass
@@ -1069,6 +1085,7 @@ def votes_visible(user):
user.pref_public_votes or
c.user_is_admin)
class ProfilePage(Reddit):
"""Container for a user's profile page. As such, the Account
object of the user must be passed in as the first argument, along
@@ -3549,3 +3566,15 @@ class TryCompact(Reddit):
u.set_extension("mobile")
self.mobile = u.unparse()
Reddit.__init__(self, **kw)
class AccountActivityPage(BoringPage):
def __init__(self):
super(AccountActivityPage, self).__init__(_("account activity"))
def content(self):
return UserIPHistory()
class UserIPHistory(Templated):
def __init__(self):
self.ips = ips_by_account_id(c.user._id)
super(UserIPHistory, self).__init__()

View File

@@ -154,6 +154,9 @@ string_dict = dict(
gold_summary_signed_gift = _("You're about to give %(amount)s of reddit gold to %(recipient)s, who will be told that it came from you."),
gold_summary_anonymous_gift = _("You're about to give %(amount)s of reddit gold to %(recipient)s. It will be an anonymous gift."),
unvotable_message = _("sorry, this has been archived and can no longer be voted on"),
account_activity_blurb = _("This page shows a history of recent activity on your account. If you notice unusual activity, you should change your password immediately. Location information is guessed from your computer's IP address and may be wildly wrong, especially for visits from mobile devices."),
your_current_ip_is = _("You are currently accessing reddit from this IP address: %(address)s."),
)
class StringHandler(object):

View File

@@ -510,7 +510,23 @@ ul.flat-vert {text-align: left;}
font-size: 110%;
}
.account-activity-box {
text-align: center;
}
#account-activity table {
margin: 2em 0 0 2em;
width: 45em;
font-size: larger;
}
#account-activity th {
font-weight: bold;
}
#account-activity td {
padding: .5em 0;
}
.infotable { margin-top: 5px; margin-bottom: 10px; }
.infotable .small { font-size: smaller; }

View File

@@ -0,0 +1,25 @@
## The contents of this file are subject to the Common Public Attribution
## License Version 1.0. (the "License"); you may not use this file except in
## compliance with the License. You may obtain a copy of the License at
## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
## License Version 1.1, but Sections 14 and 15 have been added to cover use of
## software over a computer network and provide for limited attribution for the
## Original Developer. In addition, Exhibit A has been modified to be consistent
## with Exhibit B.
##
## Software distributed under the License is distributed on an "AS IS" basis,
## WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
## the specific language governing rights and limitations under the License.
##
## The Original Code is Reddit.
##
## The Original Developer is the Initial Developer. The Initial Developer of the
## Original Code is CondeNet, Inc.
##
## All portions of the code written by CondeNet are Copyright (c) 2006-2010
## CondeNet, Inc. All Rights Reserved.
###############################################################################
<div class="account-activity-box">
<p><a href="/account-activity">${_("account activity")}</a></p>
</div>

View File

@@ -0,0 +1,55 @@
## The contents of this file are subject to the Common Public Attribution
## License Version 1.0. (the "License"); you may not use this file except in
## compliance with the License. You may obtain a copy of the License at
## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
## License Version 1.1, but Sections 14 and 15 have been added to cover use of
## software over a computer network and provide for limited attribution for the
## Original Developer. In addition, Exhibit A has been modified to be consistent
## with Exhibit B.
##
## Software distributed under the License is distributed on an "AS IS" basis,
## WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
## the specific language governing rights and limitations under the License.
##
## The Original Code is Reddit.
##
## The Original Developer is the Initial Developer. The Initial Developer of
## the Original Code is CondeNet, Inc.
##
## All portions of the code written by CondeNet are Copyright (c) 2006-2010
## CondeNet, Inc. All Rights Reserved.
################################################################################
<%namespace file="utils.html" import="timestamp"/>
<%
from r2.lib.strings import strings
ip_format = {'address': request.ip}
%>
<div id="account-activity" class="instructions">
<h1>${_("Recent activity on your account")}</h1>
<p>${strings.account_activity_blurb}</p>
<p>${strings.your_current_ip_is % ip_format}</p>
<table>
<thead>
<tr>
<th>${_("IP address")}</th>
<th>${_("Location")}</th>
<th>${_("Last Visit")}</th>
</tr>
</thead>
<tbody>
% for ip, last_visit, location in thing.ips[:10]:
<tr>
<td>${ip}</td>
<td>${location.get('country_name', '')}</td>
<td>${timestamp(last_visit)}&#32;${_('ago')}</td>
</tr>
% endfor
</tbody>
</table>
</div>