Skip to content

Commit 91bd72e

Browse files
committed
Merge branch 'release/v0.6.0'
2 parents b93e837 + 73d6558 commit 91bd72e

18 files changed

+553
-153
lines changed

CHANGELOG.md

+17-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,23 @@
33
All notable changes to this project will be documented in this file.
44
This project adheres to [Semantic Versioning](http://semver.org/).
55

6-
## [Unreleased]
6+
## v0.6.0
7+
8+
### Changed
9+
- Change the structure of the CLI actions
10+
- Renamed the "show-status" action to "filters status"
11+
- Renamed the "update-filters" action to "filters update"
12+
- Renamed the "remove-filters" action to "filters remove"
13+
- Renamed the "list-spam-domains" action to "domains list"
14+
- Renamed the "find-spam-domains" action to "domains find"
15+
- The spam-protection status calculation is now based on the number of spam domain names that are blocked by the existing filters - opposed to the number of filters which are up-to-date.
16+
- Print status updates when removing the spam-filters from an account
17+
18+
### Added
19+
- Add a logo for ga-spam-control
20+
- Add animations/screencasts that illustrate the available actions and usage scenarios for ga-spam-control
21+
22+
## v0.5.0
723

824
### Added
925
- Add a roadmap to the README.md

README.md

+71-36
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
Command-line utility for automating the fight against Google Analytics referral spam
44

5-
Google Analytics [referrer spam](https://en.wikipedia.org/wiki/Referer_spam) is pain.
6-
There are hundreds of known referrer spam domains and every other day a new one pops up. And the only way to keep the spammers from skewing your web analytics reports is to block these spam domain names one by one.
5+
Google Analytics [referrer spam](https://en.wikipedia.org/wiki/Referer_spam) is huge and never ending pain.
6+
There are hundreds of known referrer spam domains and every other day a new one pops up. And the only way to keep the spammers from skewing your web analytics reports is to their stupid domain names – one by one.
7+
8+
![ga-spam-control logo](files/assets/ga-spam-control-logo-300x200.png)
79

810
**ga-spam-control** is a small command-line utility that keeps your Google Analytics spam filters up-to-date, automatically.
911

@@ -27,90 +29,122 @@ The command line utility provides the following actions.
2729

2830
In order to protect your Google Analytics account from spam **ga-spam-control** creates filters which blocks known referrer spam domains from your analytics reports. These are the commands that help you to review and update your spam filters:
2931

30-
1. Action: **show-status**
31-
Display the spam-control status of all your accounts or for a specific account
32-
2. Action: **update-filters**
33-
Create or update the spam-control filters for a specific account
34-
3. Action: **remove-filters**
35-
Remove all spam-control filters from an account
32+
- **filters status** displays the spam-control status of all your accounts or for a specific account
33+
- **filters update** creates or updates the spam-control filters for a specific account
34+
- **filters remove** removes all previously created spam-control filters from an account
3635

3736
**Referrer Spam Domains Actions**
3837

3938
The basis for the spam filters is an up-to-date list of known referrer spam domains. And with these commands you can review and update the spam-domain lists:
4039

41-
1. Action: **list-spam-domains**
42-
Print a list of all currently known referrer spam domains
43-
2. Action: **update-spam-domains**
44-
Update the list of referrer spam domain names.
45-
3. Action: **find-spam-domains**
46-
Manually review the last `n` days of analytics data and mark domain names as spam
40+
- **domains list** prints a list of all currently known referrer spam domains
41+
- **domains update** downloads the latest referrer spam domain name lists and updates your local list of known referrer spam domains
42+
- **domains find** allows you to manually review the last `n` days of analytics data and mark domain names as spam
4743

4844
Which domains are currently considered spam is stored in the `~/.ga-spam-control/spam-domains/community.txt` and `~/.ga-spam-control/spam-domains/personal.txt`.
4945

50-
## Usage
46+
## Using ga-spam-control
5147

5248
```bash
5349
ga-spam-control <command> [<args> ...]
5450
```
5551

56-
### Print help information
52+
### Help
53+
54+
Print information about the available actions:
55+
56+
```bash
57+
ga-spam-control help
58+
```
59+
60+
Print detailed help information about the different arguments and flags of a specific action:
5761

5862
```bash
59-
ga-spam-control --help
63+
ga-spam-control help <actionname>
6064
```
6165

62-
### Display spam-control status
66+
### Authorizing ga-spam-control to access your Google Analytics accounts
67+
68+
The first time you perform an action, you will be displayed an oAuth authorization dialog.
69+
If you permit the requested rights the authentication token will be stored in your home directory (`~/.ga-spam-control/credentials.json`).
70+
71+
![Animation: Authorizing ga-spam-control to access your Google Analytics accounts](files/usage/02-authorize.gif)
72+
73+
To sign out you can either delete the file or de-authorize the "Google Analytics Spam Control" app in your Google App Permissions at https://security.google.com/settings/security/permissions.
74+
75+
### Get your spam-Control status
6376

64-
Display the current spam-control **show-status** for all accounts that you have access to:
77+
Display the current spam-control **status** for all accounts that you have access to:
6578

6679
```bash
67-
ga-spam-control show-status
80+
ga-spam-control filters status
6881
```
6982

7083
Display the spam-control status in a parseable format:
7184

7285
```bash
73-
ga-spam-control show-status --quiet
86+
ga-spam-control filters status --quiet
7487
```
7588

7689
Display the current spam-control **status** for a specific Google Analytics account:
7790

7891
```bash
79-
ga-spam-control show-status <accountID>
92+
ga-spam-control filters status <accountID>
8093
```
8194

82-
### Install or update spam-control filters
95+
![Animation: Displaying your current spam-control status with ga-spam-control filters status](files/usage/03-filters-status.gif)
96+
97+
### Install or update filters
8398

84-
**update** the spam-control filters for a specific Google Analytics account:
99+
Create or update the spam-control filters of a given Google Analytics account:
85100

86101
```bash
87-
ga-spam-control update-filters <accountID>
102+
ga-spam-control filters update <accountID>
88103
```
89104

90-
### Uninstall spam-control filters
105+
![Animation: Installing or updating spam-control filters using ga-spam-control filters update](files/usage/04-filters-update.gif)
91106

92-
**remove** the spam-control filters for a specific Google Analytics account:
107+
### Uninstall filters
108+
109+
Remove the spam-control filters of a given Google Analytics account:
93110

94111
```bash
95-
ga-spam-control remove-filters <accountID>
112+
ga-spam-control filters remove <accountID>
96113
```
97114

98-
### Find new referrer spam in your accounts
115+
This will simply remove all filters that ga-spam-control created earlier.
116+
117+
### List all known spam domains
99118

100-
The **find-spam-domains** displays referrer domain names from the last `n ` days of analytics data to you for review.
119+
Print a list of your known referrer spam domains names (community & personal):
101120

102121
```bash
103-
ga-spam-control find-spam-domains <accountID> <numberOfDaysToLookBack>
122+
ga-spam-control domains list
104123
```
105124

106-
By default ga-spam-control will use the last 90 days of analytics data. But if you want to review less or more days you can specify the number of days yourself.
125+
![Animation: Displaying a list of all known referrer spam domain names with ga-spam-control domains list](files/usage/05-domains-list.gif)
107126

108-
**Authentication**
127+
### Update your list of known spam domains
109128

110-
The first time you perform an action, you will be displayed an oAuth authorization dialog.
111-
If you permit the requested rights the authentication token will be stored in your home directory (`~/.ga-spam-control/credentials.json`).
129+
Update your local community list of known referrer spam domain names:
112130

113-
To sign out you can either delete the file or de-authorize the "Google Analytics Spam Control" app in your Google App Permissions at https://security.google.com/settings/security/permissions.
131+
```bash
132+
ga-spam-control domains update
133+
```
134+
135+
![Animation: Downloading the latest referrer spam domain names with ga-spam-control domains update](files/usage/06-domains-update.gif)
136+
137+
### Find new spam domains
138+
139+
Find referrer spam domain names in your Google Analtics data. Review the hostnames of the last `n` days of one of your Google Analytics accounts and mark those which you consider spam. All marked domain names will be added to your personal referrer spam list:
140+
141+
```bash
142+
ga-spam-control domains find <accountID> <numberOfDaysToLookBack>
143+
```
144+
145+
![Animation: Locating new referrer spam domain names in your Google Analytics reports with ga-spam-control domains find](files/usage/07-domains-find.gif)
146+
147+
By default ga-spam-control will use the last 90 days of analytics data. But if you want to review less or more days you can specify the number of days yourself.
114148

115149
## Installation
116150

@@ -140,6 +174,7 @@ See [LICENSE](LICENSE) for the full license text.
140174
Ideally Google would just include a spam-protection into Google Analytics but until then here are some ideas for additional features and possible improvements:
141175

142176
- Make remote spam domain providers configurable
177+
- Publish spam domain names that you found in your Google Analytics accounts back to the community lists.
143178
- Populate my own list of known referrer spam domains with the results from the `find-spam-domains` action.
144179
- Automatic daily upload from the ga-spam-control clients
145180
- Review of the additions by trusted community members or by a tool which checks the listed website

cli/main.go

+31-21
Original file line numberDiff line numberDiff line change
@@ -52,67 +52,77 @@ func main() {
5252
// and performs the selected action.
5353
func handleCommandlineArguments(args []string) {
5454
app := kingpin.New("ga-spam-control", "Command-line utility for keeping your Google Analytics referrer spam filters up-to-date")
55-
app.Version("0.5.0")
55+
app.Version("0.6.0")
5656

57-
status := app.Command("show-status", "Display the spam-control status of your accounts")
58-
statusAccountID := status.Arg("accountID", "Google Analytics account ID").String()
59-
statusQuiet := status.Flag("quiet", "Display spam-protection status in a parsable format").Short('q').Bool()
57+
// filters
58+
filtersCommand := app.Command("filters", "Manage spam filters")
6059

61-
update := app.Command("update-filters", "Update the spam filters for the given account")
62-
updateAccountID := update.Arg("accountID", "Google Analytics account ID").Required().String()
60+
statusCommand := filtersCommand.Command("status", "Show the spam-control status of your accounts")
61+
statusCommandAccountID := statusCommand.Arg("accountID", "Google Analytics account ID").String()
62+
statusCommandQuiet := statusCommand.Flag("quiet", "Display spam-protection status in a parsable format").Short('q').Bool()
6363

64-
remove := app.Command("remove-filters", "Remove all spam filters from an account")
65-
removeAccountID := remove.Arg("accountID", "Google Analytics account ID").Required().String()
64+
updateFiltersCommand := filtersCommand.Command("update", "Update the spam filters for the given account")
65+
updateFiltersAccountID := updateFiltersCommand.Arg("accountID", "Google Analytics account ID").Required().String()
6666

67-
listSpamDomains := app.Command("list-spam-domains", "List all currently known spam domains")
67+
removeFiltersCommand := filtersCommand.Command("remove", "Remove all spam filters from an account")
68+
removeFiltersAccountID := removeFiltersCommand.Arg("accountID", "Google Analytics account ID").Required().String()
6869

69-
updateSpamDomains := app.Command("update-spam-domains", fmt.Sprintf("Update your list of known referrer spam domains (%q)", communitySpamListFilePath))
70-
updateSpamDomainsQuiet := updateSpamDomains.Flag("quiet", "Display results in a parsable format").Short('q').Bool()
70+
// domains
71+
domainsCommand := app.Command("domains", "Manage spam domains")
72+
listDomainsCommand := domainsCommand.Command("list", "List all currently known spam domains")
7173

72-
findSpamDomains := app.Command("find-spam-domains", fmt.Sprintf("Find new referrer spam domains in your analytics data and write them to your private referrer spam list (%q)", personalSpamListFilePath))
74+
updateSpamDomainsCommand := domainsCommand.Command("update", fmt.Sprintf("Update your list of known referrer spam domains (%q)", communitySpamListFilePath))
75+
updateSpamDomainsQuiet := updateSpamDomainsCommand.Flag("quiet", "Display results in a parsable format").Short('q').Bool()
76+
77+
findSpamDomains := domainsCommand.Command("find", fmt.Sprintf("Find new referrer spam domains in your analytics data and write them to your private referrer spam list (%q)", personalSpamListFilePath))
7378
findSpamDomainsAccountID := findSpamDomains.Arg("accountID", "Google Analytics account ID").Required().String()
7479
findSpamDomainsNumberOfDays := findSpamDomains.Arg("days", "The number of days to look back").Default("90").Int()
7580
findSpamDomainsQuiet := findSpamDomains.Flag("quiet", "Display results in a parsable format").Short('q').Bool()
7681

77-
switch kingpin.MustParse(app.Parse(args)) {
82+
command, err := app.Parse(args)
83+
if err != nil {
84+
app.Fatalf("%s", err.Error())
85+
}
86+
87+
switch command {
7888

79-
case status.FullCommand():
89+
case statusCommand.FullCommand():
8090
// Display status
8191
cli, err := newCLI()
8292
if err != nil {
8393
app.Fatalf("%s", err.Error())
8494
}
8595

86-
statusError := cli.Status(*statusAccountID, *statusQuiet)
96+
statusError := cli.Status(*statusCommandAccountID, *statusCommandQuiet)
8797
if statusError != nil {
8898
app.Fatalf("%s", statusError.Error())
8999
}
90100

91-
case update.FullCommand():
101+
case updateFiltersCommand.FullCommand():
92102
// Update filters
93103
cli, err := newCLI()
94104
if err != nil {
95105
app.Fatalf("%s", err.Error())
96106
}
97107

98-
updateError := cli.Update(*updateAccountID)
108+
updateError := cli.Update(*updateFiltersAccountID)
99109
if updateError != nil {
100110
app.Fatalf("%s", updateError.Error())
101111
}
102112

103-
case remove.FullCommand():
113+
case removeFiltersCommand.FullCommand():
104114
// Remove spam control
105115
cli, err := newCLI()
106116
if err != nil {
107117
app.Fatalf("%s", err.Error())
108118
}
109119

110-
removeError := cli.Remove(*removeAccountID)
120+
removeError := cli.Remove(*removeFiltersAccountID)
111121
if removeError != nil {
112122
app.Fatalf("%s", removeError.Error())
113123
}
114124

115-
case updateSpamDomains.FullCommand():
125+
case updateSpamDomainsCommand.FullCommand():
116126
// update spam domains
117127
cli, err := newCLI()
118128
if err != nil {
@@ -124,7 +134,7 @@ func handleCommandlineArguments(args []string) {
124134
app.Fatalf("%s", updateSpamDomainsError.Error())
125135
}
126136

127-
case listSpamDomains.FullCommand():
137+
case listDomainsCommand.FullCommand():
128138
// list spam domains
129139
cli, err := newCLI()
130140
if err != nil {

cli/templates/logo.go

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package templates
2+
3+
// GASpamControlLogoAnsiShadow contains the ASCII-art logo of ga-spam-control ("ANSI Shadow")
4+
var GASpamControlLogoAnsiShadow = `
5+
██████╗ █████╗ ███████╗██████╗ █████╗ ███╗ ███╗
6+
██╔════╝ ██╔══██╗ ██╔════╝██╔══██╗██╔══██╗████╗ ████║
7+
██║ ███╗███████║ ███████╗██████╔╝███████║██╔████╔██║
8+
██║ ██║██╔══██║ ╚════██║██╔═══╝ ██╔══██║██║╚██╔╝██║
9+
╚██████╔╝██║ ██║ ███████║██║ ██║ ██║██║ ╚═╝ ██║
10+
╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝
11+
12+
██████╗ ██████╗ ███╗ ██╗████████╗██████╗ ██████╗ ██╗
13+
██╔════╝██╔═══██╗████╗ ██║╚══██╔══╝██╔══██╗██╔═══██╗██║
14+
██║ ██║ ██║██╔██╗ ██║ ██║ ██████╔╝██║ ██║██║
15+
██║ ██║ ██║██║╚██╗██║ ██║ ██╔══██╗██║ ██║██║
16+
╚██████╗╚██████╔╝██║ ╚████║ ██║ ██║ ██║╚██████╔╝███████╗
17+
╚═════╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝
18+
`
19+
20+
// GASpamControlLogoSmallKeyboard contains the ASCII-art logo of ga-spam-control ("small keyboard")
21+
var GASpamControlLogoSmallKeyboard = `
22+
____ ____ _________ ____ ____ ____ ____
23+
||g |||a ||| |||S |||p |||a |||m ||
24+
||__|||__|||_______|||__|||__|||__|||__||
25+
|/__\|/__\|/_______\|/__\|/__\|/__\|/__\|
26+
_________ ____ ____ ____ ____ ____ ____ ____
27+
|| |||C |||o |||n |||t |||r |||o |||l ||
28+
||_______|||__|||__|||__|||__|||__|||__|||__||
29+
|/_______\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|
30+
`
31+
32+
// GASpamControlLogoBloody contains the ASCII-art logo of ga-spam-control ("bloody")
33+
var GASpamControlLogoBloody = `
34+
▄████ ▄▄▄ ██████ ██▓███ ▄▄▄ ███▄ ▄███▓
35+
██▒ ▀█▒▒████▄ ▒██ ▒ ▓██░ ██▒▒████▄ ▓██▒▀█▀ ██▒
36+
▒██░▄▄▄░▒██ ▀█▄ ░ ▓██▄ ▓██░ ██▓▒▒██ ▀█▄ ▓██ ▓██░
37+
░▓█ ██▓░██▄▄▄▄██ ▒ ██▒▒██▄█▓▒ ▒░██▄▄▄▄██ ▒██ ▒██
38+
░▒▓███▀▒ ▓█ ▓██▒ ▒██████▒▒▒██▒ ░ ░ ▓█ ▓██▒▒██▒ ░██▒
39+
░▒ ▒ ▒▒ ▓▒█░ ▒ ▒▓▒ ▒ ░▒▓▒░ ░ ░ ▒▒ ▓▒█░░ ▒░ ░ ░
40+
░ ░ ▒ ▒▒ ░ ░ ░▒ ░ ░░▒ ░ ▒ ▒▒ ░░ ░ ░
41+
░ ░ ░ ░ ▒ ░ ░ ░ ░░ ░ ▒ ░ ░
42+
░ ░ ░ ░ ░ ░ ░
43+
44+
▄████▄ ▒█████ ███▄ █ ▄▄▄█████▓ ██▀███ ▒█████ ██▓
45+
▒██▀ ▀█ ▒██▒ ██▒ ██ ▀█ █ ▓ ██▒ ▓▒▓██ ▒ ██▒▒██▒ ██▒▓██▒
46+
▒▓█ ▄ ▒██░ ██▒▓██ ▀█ ██▒▒ ▓██░ ▒░▓██ ░▄█ ▒▒██░ ██▒▒██░
47+
▒▓▓▄ ▄██▒▒██ ██░▓██▒ ▐▌██▒░ ▓██▓ ░ ▒██▀▀█▄ ▒██ ██░▒██░
48+
▒ ▓███▀ ░░ ████▓▒░▒██░ ▓██░ ▒██▒ ░ ░██▓ ▒██▒░ ████▓▒░░██████▒
49+
░ ░▒ ▒ ░░ ▒░▒░▒░ ░ ▒░ ▒ ▒ ▒ ░░ ░ ▒▓ ░▒▓░░ ▒░▒░▒░ ░ ▒░▓ ░
50+
░ ▒ ░ ▒ ▒░ ░ ░░ ░ ▒░ ░ ░▒ ░ ▒░ ░ ▒ ▒░ ░ ░ ▒ ░
51+
░ ░ ░ ░ ▒ ░ ░ ░ ░ ░░ ░ ░ ░ ░ ▒ ░ ░
52+
░ ░ ░ ░ ░ ░ ░ ░ ░ ░
53+
54+
`
55+
56+
// GASpamControlLogoGraceful contains the ASCII-art logo of ga-spam-control ("graceful")
57+
var GASpamControlLogoGraceful = `
58+
___ __ ____ ____ __ _ _
59+
/ __) / _\ / ___)( _ \ / _\ ( \/ )
60+
( (_ \/ \ \___ \ ) __// \/ \/ \
61+
\___/\_/\_/ (____/(__) \_/\_/\_)(_/
62+
___ __ __ _ ____ ____ __ __
63+
/ __)/ \ ( ( \(_ _)( _ \ / \ ( )
64+
( (__( O )/ / )( ) /( O )/ (_/\
65+
\___)\__/ \_)__) (__) (__\_) \__/ \____/
66+
`

0 commit comments

Comments
 (0)