mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2025-01-10 18:27:25 +03:00
Optimized visits parser to act over the normalized list of visits
This commit is contained in:
parent
fafe920b7b
commit
52dbeb6201
3 changed files with 41 additions and 37 deletions
|
@ -87,8 +87,8 @@ const ShortUrlVisits = ({ processStatsFromVisits, normalizeVisits }, OpenMapModa
|
|||
const showTableControls = !loading && visits.length > 0;
|
||||
const normalizedVisits = useMemo(() => normalizeVisits(visits), [ visits ]);
|
||||
const { os, browsers, referrers, countries, cities, citiesForMap } = useMemo(
|
||||
() => processStatsFromVisits(visits),
|
||||
[ visits ]
|
||||
() => processStatsFromVisits(normalizedVisits),
|
||||
[ normalizedVisits ]
|
||||
);
|
||||
const mapLocations = values(citiesForMap);
|
||||
|
||||
|
|
|
@ -1,60 +1,52 @@
|
|||
import { isEmpty, isNil, map } from 'ramda';
|
||||
import { isNil, map } from 'ramda';
|
||||
import { browserFromUserAgent, extractDomain, osFromUserAgent } from '../../utils/helpers/visits';
|
||||
import { hasValue } from '../../utils/utils';
|
||||
|
||||
const visitLocationHasProperty = (visitLocation, propertyName) =>
|
||||
!isNil(visitLocation)
|
||||
&& !isNil(visitLocation[propertyName])
|
||||
&& !isEmpty(visitLocation[propertyName]);
|
||||
|
||||
const updateOsStatsForVisit = (osStats, { userAgent }) => {
|
||||
const os = osFromUserAgent(userAgent);
|
||||
const visitHasProperty = (visit, propertyName) => !isNil(visit) && hasValue(visit[propertyName]);
|
||||
|
||||
const updateOsStatsForVisit = (osStats, { os }) => {
|
||||
osStats[os] = (osStats[os] || 0) + 1;
|
||||
};
|
||||
|
||||
const updateBrowsersStatsForVisit = (browsersStats, { userAgent }) => {
|
||||
const browser = browserFromUserAgent(userAgent);
|
||||
|
||||
const updateBrowsersStatsForVisit = (browsersStats, { browser }) => {
|
||||
browsersStats[browser] = (browsersStats[browser] || 0) + 1;
|
||||
};
|
||||
|
||||
const updateReferrersStatsForVisit = (referrersStats, { referer }) => {
|
||||
const domain = extractDomain(referer);
|
||||
|
||||
const updateReferrersStatsForVisit = (referrersStats, { referer: domain }) => {
|
||||
referrersStats[domain] = (referrersStats[domain] || 0) + 1;
|
||||
};
|
||||
|
||||
const updateLocationsStatsForVisit = (propertyName) => (stats, { visitLocation }) => {
|
||||
const hasLocationProperty = visitLocationHasProperty(visitLocation, propertyName);
|
||||
const value = hasLocationProperty ? visitLocation[propertyName] : 'Unknown';
|
||||
const updateLocationsStatsForVisit = (propertyName) => (stats, visit) => {
|
||||
const hasLocationProperty = visitHasProperty(visit, propertyName);
|
||||
const value = hasLocationProperty ? visit[propertyName] : 'Unknown';
|
||||
|
||||
stats[value] = (stats[value] || 0) + 1;
|
||||
};
|
||||
|
||||
const updateCountriesStatsForVisit = updateLocationsStatsForVisit('countryName');
|
||||
const updateCitiesStatsForVisit = updateLocationsStatsForVisit('cityName');
|
||||
const updateCountriesStatsForVisit = updateLocationsStatsForVisit('country');
|
||||
const updateCitiesStatsForVisit = updateLocationsStatsForVisit('city');
|
||||
|
||||
const updateCitiesForMapForVisit = (citiesForMapStats, { visitLocation }) => {
|
||||
if (!visitLocationHasProperty(visitLocation, 'cityName')) {
|
||||
const updateCitiesForMapForVisit = (citiesForMapStats, visit) => {
|
||||
if (!visitHasProperty(visit, 'city') || visit.city === 'Unknown') {
|
||||
return;
|
||||
}
|
||||
|
||||
const { cityName, latitude, longitude } = visitLocation;
|
||||
const currentCity = citiesForMapStats[cityName] || {
|
||||
cityName,
|
||||
const { city, latitude, longitude } = visit;
|
||||
const currentCity = citiesForMapStats[city] || {
|
||||
cityName: city,
|
||||
count: 0,
|
||||
latLong: [ parseFloat(latitude), parseFloat(longitude) ],
|
||||
};
|
||||
|
||||
currentCity.count++;
|
||||
|
||||
citiesForMapStats[cityName] = currentCity;
|
||||
citiesForMapStats[city] = currentCity;
|
||||
};
|
||||
|
||||
export const processStatsFromVisits = (visits) =>
|
||||
visits.reduce(
|
||||
export const processStatsFromVisits = (normalizedVisits) =>
|
||||
normalizedVisits.reduce(
|
||||
(stats, visit) => {
|
||||
// We mutate the original object because it has a big side effect when large data sets are processed
|
||||
// We mutate the original object because it has a big performance impact when large data sets are processed
|
||||
updateOsStatsForVisit(stats.os, visit);
|
||||
updateBrowsersStatsForVisit(stats.browsers, visit);
|
||||
updateReferrersStatsForVisit(stats.referrers, visit);
|
||||
|
@ -74,4 +66,6 @@ export const normalizeVisits = map(({ userAgent, date, referer, visitLocation })
|
|||
referer: extractDomain(referer),
|
||||
country: (visitLocation && visitLocation.countryName) || 'Unknown',
|
||||
city: (visitLocation && visitLocation.cityName) || 'Unknown',
|
||||
latitude: visitLocation && visitLocation.latitude,
|
||||
longitude: visitLocation && visitLocation.longitude,
|
||||
}));
|
||||
|
|
|
@ -8,8 +8,8 @@ describe('VisitsParser', () => {
|
|||
visitLocation: {
|
||||
countryName: 'Spain',
|
||||
cityName: 'Zaragoza',
|
||||
latitude: '123.45',
|
||||
longitude: '-543.21',
|
||||
latitude: 123.45,
|
||||
longitude: -543.21,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -18,8 +18,8 @@ describe('VisitsParser', () => {
|
|||
visitLocation: {
|
||||
countryName: 'United States',
|
||||
cityName: 'New York',
|
||||
latitude: '1029',
|
||||
longitude: '6758',
|
||||
latitude: 1029,
|
||||
longitude: 6758,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -34,8 +34,8 @@ describe('VisitsParser', () => {
|
|||
visitLocation: {
|
||||
countryName: 'Spain',
|
||||
cityName: 'Zaragoza',
|
||||
latitude: '123.45',
|
||||
longitude: '-543.21',
|
||||
latitude: 123.45,
|
||||
longitude: -543.21,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -47,7 +47,7 @@ describe('VisitsParser', () => {
|
|||
let stats;
|
||||
|
||||
beforeAll(() => {
|
||||
stats = processStatsFromVisits(visits);
|
||||
stats = processStatsFromVisits(normalizeVisits(visits));
|
||||
});
|
||||
|
||||
it('properly parses OS stats', () => {
|
||||
|
@ -132,6 +132,8 @@ describe('VisitsParser', () => {
|
|||
country: 'Spain',
|
||||
city: 'Zaragoza',
|
||||
date: undefined,
|
||||
latitude: 123.45,
|
||||
longitude: -543.21,
|
||||
},
|
||||
{
|
||||
browser: 'Firefox',
|
||||
|
@ -140,6 +142,8 @@ describe('VisitsParser', () => {
|
|||
country: 'United States',
|
||||
city: 'New York',
|
||||
date: undefined,
|
||||
latitude: 1029,
|
||||
longitude: 6758,
|
||||
},
|
||||
{
|
||||
browser: 'Chrome',
|
||||
|
@ -148,6 +152,8 @@ describe('VisitsParser', () => {
|
|||
country: 'Spain',
|
||||
city: 'Unknown',
|
||||
date: undefined,
|
||||
latitude: undefined,
|
||||
longitude: undefined,
|
||||
},
|
||||
{
|
||||
browser: 'Chrome',
|
||||
|
@ -156,6 +162,8 @@ describe('VisitsParser', () => {
|
|||
country: 'Spain',
|
||||
city: 'Zaragoza',
|
||||
date: undefined,
|
||||
latitude: 123.45,
|
||||
longitude: -543.21,
|
||||
},
|
||||
{
|
||||
browser: 'Opera',
|
||||
|
@ -164,6 +172,8 @@ describe('VisitsParser', () => {
|
|||
country: 'Unknown',
|
||||
city: 'Unknown',
|
||||
date: undefined,
|
||||
latitude: undefined,
|
||||
longitude: undefined,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue