2
2
3
3
![ Punch Bag] ( ./src/punching-bag.gif )
4
4
5
- A Crystal shard for tracking and analyzing hit counts, trending items, and time-based analytics.
5
+ A Crystal shard for tracking and analyzing hit counts, trending items, time and location analytics for PostgreSQL .
6
6
7
7
[ ![ Crystal Test] ( https://github.com/dcalixto/punching_bag/actions/workflows/crystal-test.yml/badge.svg?branch=master )] ( https://github.com/dcalixto/punching_bag/actions/workflows/crystal-test.yml )
8
8
9
9
## Features
10
10
11
- - Total hit count tracking
12
- - Most hit items tracking
13
- - Time-based hit analytics
11
+ - Timezone-aware tracking using PostgreSQL's TIMESTAMPTZ
12
+ - Location-based analytics support
13
+ - Configurable hit counting
14
+ - Time-based popularity tracking
15
+ - Efficient indexing for fast queries
14
16
- Lightweight and fast
15
17
16
18
## Requirements
@@ -58,64 +60,73 @@ require "punching_bag"
58
60
Initialize database connection
59
61
60
62
``` crystal
61
- database = DB.open(DATABASE_URL)
62
- PunchingBag.db = database
63
+ PunchingBag.configure do |config|
64
+ config.database_url = "postgres://localhost/your_database"
65
+ end
63
66
```
64
67
65
- ## Initialize the Bag
68
+ ## Initialize the tracker
66
69
67
70
``` crystal
68
- bag = PunchingBag.new
71
+ # Initialize tracker
72
+ tracker = PunchingBag::Tracker.new(PunchingBag.db)
69
73
```
70
74
71
75
Record a hit
72
76
73
77
``` crystal
74
- bag.punch("Article", 1)
78
+ tracker.punch("Article", 1)
79
+ ```
80
+
81
+ Track hits with custom timestamp and timezone
82
+
83
+ ``` crystal
84
+ timestamp = Time.local(timezone: Time::Location.load("America/New_York"))
85
+ tracker.punch("Article", 1, hits: 1, timestamp: timestamp)
75
86
```
76
87
77
88
Record multiple hits
78
89
79
90
``` crystal
80
- bag .punch("Article", 1, hits: 5)
91
+ tracker .punch("Article", 1, hits: 5)
81
92
```
82
93
83
94
Record hit with timestamp
84
95
85
96
``` crystal
86
- bag .punch("Article", 1, timestamp: Time.utc - 1.day)
97
+ tracker .punch("Article", 1, timestamp: Time.utc - 1.day)
87
98
```
88
99
89
100
## Analytics
90
101
91
102
Get total hits for an item
92
103
93
104
``` crystal
94
- total = bag .total_hits("Article", 1)
105
+ total = tracker .total_hits("Article", 1)
95
106
```
96
107
97
108
Get most hit items since last week
98
109
99
110
``` crystal
100
- trending = bag .most_hit(Time.utc - 1.week)
111
+ trending = tracker .most_hit(Time.utc - 1.week)
101
112
```
102
113
103
114
Get top 10 most hit items since last month
104
115
105
116
``` crystal
106
- top_items = bag .most_hit(Time.utc - 1.month, limit: 10)
117
+ top_items = tracker .most_hit(Time.utc - 1.month, limit: 10)
107
118
```
108
119
109
120
Get average time for hits
110
121
111
122
``` crystal
112
- avg_time = bag .average_time("Article", 1)
123
+ avg_time = tracker .average_time("Article", 1)
113
124
```
114
125
115
126
Clear all recorded hits
116
127
117
128
``` crystal
118
- bag .clear
129
+ tracker .clear
119
130
```
120
131
121
132
## Example Integration
@@ -141,18 +152,18 @@ class Article
141
152
end
142
153
143
154
def track_view
144
- bag = PunchingBag.new(@@db.not_nil!)
145
- bag .punch("Article", id.not_nil!)
155
+ tracker = PunchingBag.new(@@db.not_nil!)
156
+ tracker .punch("Article", id.not_nil!)
146
157
end
147
158
148
159
def total_views
149
- bag = PunchingBag.new(@@db.not_nil!)
150
- bag .total_hits("Article", id.not_nil!)
160
+ tracker = PunchingBag.new(@@db.not_nil!)
161
+ tracker .total_hits("Article", id.not_nil!)
151
162
end
152
163
153
164
def self.trending(since = Time.utc - 1.week, limit = 10)
154
- bag = PunchingBag.new(@@db.not_nil!)
155
- bag .most_hit(since, limit: limit)
165
+ tracker = PunchingBag.new(@@db.not_nil!)
166
+ tracker .most_hit(since, limit: limit)
156
167
end
157
168
end
158
169
@@ -202,24 +213,3 @@ Daniel Calixto - creator and maintainer
202
213
## License
203
214
204
215
MIT License. See LICENSE for details.
205
-
206
- ## TODO
207
-
208
- Run the setup as follows:
209
-
210
- ``` crystal
211
- require "./punching_bag/setup"
212
-
213
- PunchingBag::Setup.run
214
- ```
215
-
216
- ## Output Example:
217
-
218
- ``` crystal
219
- Setting up development database...
220
- Database already exists.
221
- Creating tables and indexes...
222
- Punches table created or already exists.
223
- Indexes created or already exist.
224
- Setup completed successfully.
225
- ```
0 commit comments