Add user activity page

This commit is contained in:
2022-02-01 18:43:52 +01:00
parent 4985f8810b
commit 1de3bb49c5
9 changed files with 159 additions and 24 deletions

6
go.mod
View File

@@ -5,7 +5,7 @@ go 1.17
require (
fornaxian.tech/config v0.0.0-20211108212237-6133aed90586
fornaxian.tech/log v0.0.0-20211102185326-552e9b1f8640
fornaxian.tech/pixeldrain_api_client v0.0.0-20220118195948-62ff33b02665
fornaxian.tech/pixeldrain_api_client v0.0.0-20220127185304-6a60644d957e
fornaxian.tech/util v0.0.0-20211102152345-9a486dee9787
github.com/julienschmidt/httprouter v1.3.0
github.com/microcosm-cc/bluemonday v1.0.17
@@ -19,7 +19,7 @@ require (
github.com/golang/snappy v0.0.4 // indirect
github.com/gorilla/css v1.0.0 // indirect
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce // indirect
golang.org/x/net v0.0.0-20220114011407-0dd24b26b47d // indirect
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838 // indirect
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
)

25
go.sum
View File

@@ -3,13 +3,10 @@ fornaxian.tech/config v0.0.0-20211108212237-6133aed90586/go.mod h1:ULIXF4J1DbBw4
fornaxian.tech/log v0.0.0-20190617093801-1c7ce9a7c9b3/go.mod h1:OyWUNsNPlo5AmlOHvJ4s6WcStQw+9rQyBMwmTz0buEM=
fornaxian.tech/log v0.0.0-20211102185326-552e9b1f8640 h1:UPDxJwLRCfh/cv80UMSanzmZ0jIcfS1mcd0Y06HYuLw=
fornaxian.tech/log v0.0.0-20211102185326-552e9b1f8640/go.mod h1:sN82qMToeHhP2u3ehvrcE8y1IudRZJAZO9yG5OBYblo=
fornaxian.tech/pixeldrain_api_client v0.0.0-20211220185733-94b115cb883d h1:BWmYoeL3InMJFD9iIMbq170yyJ07WObJBS3soi5VuVE=
fornaxian.tech/pixeldrain_api_client v0.0.0-20211220185733-94b115cb883d/go.mod h1:uajB2ofEsefUtxjvs4m7SDyPVRlfrI3qzCSWcud47hY=
fornaxian.tech/pixeldrain_api_client v0.0.0-20220118195948-62ff33b02665 h1:2hbHYMQeQvIKB1NNGnr9BVA9CoT0wlSNToT0KZ7dHb4=
fornaxian.tech/pixeldrain_api_client v0.0.0-20220118195948-62ff33b02665/go.mod h1:uajB2ofEsefUtxjvs4m7SDyPVRlfrI3qzCSWcud47hY=
fornaxian.tech/pixeldrain_api_client v0.0.0-20220127185304-6a60644d957e h1:/PLg0AMCPx6Uft5oPb70ogK127/oWrRGadPU0kvqRv8=
fornaxian.tech/pixeldrain_api_client v0.0.0-20220127185304-6a60644d957e/go.mod h1:uajB2ofEsefUtxjvs4m7SDyPVRlfrI3qzCSWcud47hY=
fornaxian.tech/util v0.0.0-20211102152345-9a486dee9787 h1:9ujI8Qi6+FTL/YW6xQAS9DmWDMerHBe8foQvVD/G/i0=
fornaxian.tech/util v0.0.0-20211102152345-9a486dee9787/go.mod h1:FqVgfghmxTGR3l9Zx4MOMeZ9KHjiEFl3s3C0BSTvBwk=
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU=
github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
@@ -20,7 +17,6 @@ github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCS
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gocql/gocql v0.0.0-20211015133455-b225f9b53fa1 h1:px9qUCy/RNJNsfCam4m2IxWGxNuimkrioEF0vrrbPsg=
github.com/gocql/gocql v0.0.0-20211015133455-b225f9b53fa1/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8=
github.com/gocql/gocql v0.0.0-20211222173705-d73e6b1002a7 h1:jmIMM+nEO+vjz9xaRIg9sZNtNLq5nsSbsxwe1OtRwv4=
github.com/gocql/gocql v0.0.0-20211222173705-d73e6b1002a7/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8=
@@ -38,8 +34,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/microcosm-cc/bluemonday v1.0.16 h1:kHmAq2t7WPWLjiGvzKa5o3HzSfahUKiOq7fAPUiMNIc=
github.com/microcosm-cc/bluemonday v1.0.16/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM=
github.com/microcosm-cc/bluemonday v1.0.17 h1:Z1a//hgsQ4yjC+8zEkV8IWySkXnsxmdSY642CTFQb5Y=
github.com/microcosm-cc/bluemonday v1.0.17/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -49,26 +43,25 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20201217014255-9d1352758620/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce h1:Roh6XWxHFKrPgC/EQhVubSAGQ6Ozk6IdxHSzt1mR0EI=
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838 h1:71vQrMauZZhcTVK6KdYM+rklehEEwb3E+ZhaE5jrPrE=
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM=
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220114011407-0dd24b26b47d h1:1n1fc535VhN8SYtD4cDUyNlfpAF2ROMM9+11equK3hs=
golang.org/x/net v0.0.0-20220114011407-0dd24b26b47d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=

View File

@@ -1552,6 +1552,15 @@ interdogmedia.com, 17207, DIRECT
apacdex.com, 17207, DIRECT
valueimpression.com, 17207, DIRECT
quantumdex.io, 17207, DIRECT
smilewanted.com, 3583, RESELLER
appnexus.com, 10040, RESELLER, f5ab79cb980f11d1
indexexchange.com, 193216, DIRECT, 50b1c356f2c5c8fc
rubiconproject.com, 16114, DIRECT, 0bfd66d529a55807
verve.com, 15503, RESELLER, 0c8f5958fc2d6270
loopme.com, 11013, DIRECT, 6c8d5f95897a5a3b
connectad.io, 204, DIRECT, 85ac85a30c93b3e5
appnexus.com, 2579, RESELLER, f5ab79cb980f11d1
quantum-advertising.com, 6222, RESELLER
# End of Valueimpression
# Pixfuture

View File

@@ -77,7 +77,7 @@ let set_status = async (action, report_type) => {
<iframe
title="File preview"
src="/u/{report.file.id}?embed"
style="border: none; width: 100%; height: 500px; border-radius: 6px;"
style="border: none; width: 100%; height: 600px; border-radius: 16px;"
></iframe>
{/if}
</div>

View File

@@ -112,7 +112,7 @@ const logout = async (key) => {
<p>
If you delete the API key that you are currently using you will be
logged out of your account. API keys expire 90 days after the last
logged out of your account. API keys expire 30 days after the last
time they're used. If you think someone is using your account
without your authorization it's probably a good idea to delete all
your keys.

View File

@@ -0,0 +1,119 @@
<script>
import { onMount } from "svelte";
import { formatDataVolume, formatDate } from "../util/Formatting.svelte";
import Spinner from "../util/Spinner.svelte";
import Euro from "../util/Euro.svelte"
let loading = false
let months = []
const load_activity = async () => {
loading = true
try {
// We keep fetching history until we have fetched two months without
// any activity
let empty_months = 0
let now = new Date()
while (empty_months < 2) {
const resp = await fetch(
window.api_endpoint+"/user/activity/" +
now.getFullYear()+"-"+("00"+(now.getMonth()+1)).slice(-2),
)
if(resp.status >= 400) {
let json = await resp.json()
if (json.value === "authentication_failed") {
window.location = "/login"
return
} else {
throw new Error(json.message)
}
}
let month = {
rows: await resp.json(),
month: now.getFullYear()+"-"+("00"+(now.getMonth()+1)).slice(-2),
}
if (month.rows.length === 0) {
empty_months++
continue
}
months.push(month)
months = months
// Fetch the previous month
now.setMonth(now.getMonth()-1)
}
} catch (err) {
alert(err)
} finally {
loading = false
}
};
onMount(() => {
load_activity()
})
</script>
{#if loading}
<div class="spinner_container">
<Spinner />
</div>
{/if}
<section>
<h2>Account activity log</h2>
<p>
Here you can see files that have recently expired or have been blocked
for breaking the content policy.
</p>
{#each months as month}
<h3>{month.month}</h3>
<div class="table_scroll">
<table style="text-align: left;">
<thead>
<tr>
<td>Time</td>
<td>Event</td>
<td>File name</td>
<td>File removal reason</td>
</tr>
</thead>
<tbody>
{#each month.rows as row}
<tr>
<td>
{formatDate(row.time, true, true, false)}
</td>
<td>
{#if row.event === "file_instance_blocked"}
File blocked for abuse
{:else if row.event === "file_instance_expired"}
File expired
{/if}
</td>
<td>
{row.file_name}
</td>
<td>
{row.file_removal_reason}
</td>
</tr>
{/each}
</tbody>
</table>
</div>
{/each}
</section>
<style>
.spinner_container {
position: absolute;
top: 10px;
left: 10px;
height: 100px;
width: 100px;
z-index: 1000;
}
</style>

View File

@@ -6,6 +6,7 @@ import APIKeys from "./APIKeys.svelte";
import Transactions from "./Transactions.svelte";
import Subscription from "./Subscription.svelte";
import ConnectApp from "./ConnectApp.svelte";
import ActivityLog from "./ActivityLog.svelte";
let page = ""
@@ -58,6 +59,13 @@ onMount(() => {
<i class="icon">vpn_key</i>
API keys
</a>
<a class="button"
href="/user/activity"
class:button_highlight={page === "activity"}
on:click|preventDefault={() => {navigate("activity", "Activity log")}}>
<i class="icon">list</i>
Activity log
</a>
<a class="button"
href="/user/subscription"
class:button_highlight={page === "subscription"}
@@ -84,6 +92,8 @@ onMount(() => {
<AccountSettings/>
{:else if page === "api_keys"}
<APIKeys/>
{:else if page === "activity"}
<ActivityLog/>
{:else if page === "connect_app"}
<ConnectApp/>
{:else if page === "transactions"}

View File

@@ -10,9 +10,11 @@ let months = []
const load_transactions = async () => {
loading = true
try {
// We keep fetching history until there is no history left
// We keep fetching history until we have fetched three months without
// any transactions
let empty_months = 0
let now = new Date()
while (true) {
while (empty_months < 3) {
const resp = await fetch(
window.api_endpoint+"/user/transactions/" +
now.getFullYear()+"-"+("00"+(now.getMonth()+1)).slice(-2),
@@ -39,7 +41,8 @@ const load_transactions = async () => {
}
if (month.rows.length === 0) {
break
empty_months++
continue
}
month.rows.forEach(row => {

View File

@@ -180,6 +180,7 @@ func New(
{GET, "user/home" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})},
{GET, "user/settings" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})},
{GET, "user/api_keys" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})},
{GET, "user/activity" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})},
{GET, "user/connect_app" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})},
{GET, "user/transactions" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})},
{GET, "user/subscription" /* */, wc.serveTemplate("user_home", handlerOpts{Auth: true})},