Skip to content

Commit 116748c

Browse files
feat: track clicks!
1 parent 83677a5 commit 116748c

File tree

7 files changed

+164
-9
lines changed

7 files changed

+164
-9
lines changed

linklite/linklite/doctype/short_link/short_link.json

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"autoname": "field:short_link",
55
"creation": "2024-12-21 12:43:49.300176",
66
"doctype": "DocType",
7-
"engine": "InnoDB",
7+
"engine": "MyISAM",
88
"field_order": [
99
"destination_url",
1010
"column_break_awjo",
@@ -39,8 +39,13 @@
3939
}
4040
],
4141
"index_web_pages_for_search": 1,
42-
"links": [],
43-
"modified": "2024-12-21 12:45:50.795245",
42+
"links": [
43+
{
44+
"link_doctype": "Short Link Click",
45+
"link_fieldname": "link"
46+
}
47+
],
48+
"modified": "2024-12-21 13:04:17.613091",
4449
"modified_by": "Administrator",
4550
"module": "LinkLite",
4651
"name": "Short Link",
@@ -63,4 +68,4 @@
6368
"sort_field": "creation",
6469
"sort_order": "DESC",
6570
"states": []
66-
}
71+
}

linklite/linklite/doctype/short_link_click/__init__.py

Whitespace-only changes.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Copyright (c) 2024, Build With Hussain and contributors
2+
// For license information, please see license.txt
3+
4+
// frappe.ui.form.on("Short Link Click", {
5+
// refresh(frm) {
6+
7+
// },
8+
// });
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
{
2+
"actions": [],
3+
"allow_rename": 1,
4+
"creation": "2024-12-21 12:51:40.642856",
5+
"doctype": "DocType",
6+
"engine": "InnoDB",
7+
"field_order": [
8+
"ip",
9+
"user_agent",
10+
"link",
11+
"column_break_fifj",
12+
"referrer",
13+
"utm",
14+
"section_break_uflm",
15+
"amended_from"
16+
],
17+
"fields": [
18+
{
19+
"fieldname": "section_break_uflm",
20+
"fieldtype": "Section Break"
21+
},
22+
{
23+
"fieldname": "amended_from",
24+
"fieldtype": "Link",
25+
"label": "Amended From",
26+
"no_copy": 1,
27+
"options": "Short Link Click",
28+
"print_hide": 1,
29+
"read_only": 1,
30+
"search_index": 1
31+
},
32+
{
33+
"fieldname": "ip",
34+
"fieldtype": "Data",
35+
"label": "IP"
36+
},
37+
{
38+
"fieldname": "user_agent",
39+
"fieldtype": "Data",
40+
"label": "User Agent"
41+
},
42+
{
43+
"fieldname": "column_break_fifj",
44+
"fieldtype": "Column Break"
45+
},
46+
{
47+
"fieldname": "referrer",
48+
"fieldtype": "Data",
49+
"label": "Referrer"
50+
},
51+
{
52+
"fieldname": "utm",
53+
"fieldtype": "Data",
54+
"label": "UTM"
55+
},
56+
{
57+
"fieldname": "link",
58+
"fieldtype": "Link",
59+
"in_list_view": 1,
60+
"label": "Link",
61+
"options": "Short Link",
62+
"reqd": 1
63+
}
64+
],
65+
"index_web_pages_for_search": 1,
66+
"is_submittable": 1,
67+
"links": [],
68+
"modified": "2024-12-21 12:52:51.135308",
69+
"modified_by": "Administrator",
70+
"module": "LinkLite",
71+
"name": "Short Link Click",
72+
"owner": "Administrator",
73+
"permissions": [
74+
{
75+
"create": 1,
76+
"delete": 1,
77+
"email": 1,
78+
"export": 1,
79+
"print": 1,
80+
"read": 1,
81+
"report": 1,
82+
"role": "System Manager",
83+
"share": 1,
84+
"submit": 1,
85+
"write": 1
86+
}
87+
],
88+
"sort_field": "creation",
89+
"sort_order": "DESC",
90+
"states": []
91+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright (c) 2024, Build With Hussain and contributors
2+
# For license information, please see license.txt
3+
4+
# import frappe
5+
from frappe.model.document import Document
6+
7+
8+
class ShortLinkClick(Document):
9+
pass
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Copyright (c) 2024, Build With Hussain and Contributors
2+
# See license.txt
3+
4+
# import frappe
5+
from frappe.tests import IntegrationTestCase, UnitTestCase
6+
7+
8+
# On IntegrationTestCase, the doctype test records and all
9+
# link-field test record depdendencies are recursively loaded
10+
# Use these module variables to add/remove to/from that list
11+
EXTRA_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
12+
IGNORE_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
13+
14+
15+
class UnitTestShortLinkClick(UnitTestCase):
16+
"""
17+
Unit tests for ShortLinkClick.
18+
Use this class for testing individual functions and methods.
19+
"""
20+
21+
pass
22+
23+
24+
class IntegrationTestShortLinkClick(IntegrationTestCase):
25+
"""
26+
Integration tests for ShortLinkClick.
27+
Use this class for testing interactions between multiple components.
28+
"""
29+
30+
pass

linklite/utils.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,26 @@
11
import frappe
2-
32
from frappe.website.path_resolver import resolve_path as original_resolve_path
43

4+
55
def path_resolver(path: str):
6-
# if we want to handle the short link
6+
# TODO: not handling "/gin?q=abc"
77
if frappe.db.exists("Short Link", {"short_link": path}):
8-
# we want to redirect
9-
destination = frappe.db.get_value("Short Link", {"short_link": path}, "destination_url")
10-
frappe.redirect(destination)
8+
short_link = frappe.db.get_value(
9+
"Short Link", {"short_link": path}, ["destination_url", "name"], as_dict=True
10+
)
11+
12+
click = frappe.new_doc("Short Link Click")
13+
14+
request_headers = frappe.request.headers
15+
click.ip = request_headers.get("X-Real-Ip")
16+
click.user_agent = request_headers.get("User-Agent")
17+
click.referrer = request_headers.get("Referer")
18+
19+
click.link = short_link.name
20+
click.insert().submit()
21+
frappe.db.commit() # to remove once MyISAM
1122

23+
frappe.redirect(short_link.destination_url)
1224

1325
# else pass it on!
1426
return original_resolve_path(path)

0 commit comments

Comments
 (0)