mirror of https://github.com/oxen-io/session-ios
Merge branch 'charlesmchen/analyticsStub'
commit
87719a3bfb
@ -0,0 +1,120 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import datetime
|
||||||
|
import argparse
|
||||||
|
import commands
|
||||||
|
|
||||||
|
|
||||||
|
git_repo_path = os.path.abspath(subprocess.check_output(['git', 'rev-parse', '--show-toplevel']).strip())
|
||||||
|
|
||||||
|
|
||||||
|
def splitall(path):
|
||||||
|
allparts = []
|
||||||
|
while 1:
|
||||||
|
parts = os.path.split(path)
|
||||||
|
if parts[0] == path: # sentinel for absolute paths
|
||||||
|
allparts.insert(0, parts[0])
|
||||||
|
break
|
||||||
|
elif parts[1] == path: # sentinel for relative paths
|
||||||
|
allparts.insert(0, parts[1])
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
path = parts[0]
|
||||||
|
allparts.insert(0, parts[1])
|
||||||
|
return allparts
|
||||||
|
|
||||||
|
|
||||||
|
def process(filepath):
|
||||||
|
with open(filepath, 'rt') as f:
|
||||||
|
text = f.read()
|
||||||
|
original_text = text
|
||||||
|
|
||||||
|
lines = text.split('\n')
|
||||||
|
while lines and lines[0].startswith('//'):
|
||||||
|
lines = lines[1:]
|
||||||
|
text = '\n'.join(lines)
|
||||||
|
text = text.strip()
|
||||||
|
|
||||||
|
header = '''//
|
||||||
|
// Copyright (c) %s Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
''' % (
|
||||||
|
datetime.datetime.now().year,
|
||||||
|
)
|
||||||
|
text = header + text + '\n'
|
||||||
|
|
||||||
|
if original_text == text:
|
||||||
|
return
|
||||||
|
|
||||||
|
short_filepath = filepath[len(git_repo_path):]
|
||||||
|
if short_filepath.startswith(os.sep):
|
||||||
|
short_filepath = short_filepath[len(os.sep):]
|
||||||
|
print 'Updating:', short_filepath
|
||||||
|
|
||||||
|
with open(filepath, 'wt') as f:
|
||||||
|
f.write(text)
|
||||||
|
|
||||||
|
|
||||||
|
def should_ignore_path(path):
|
||||||
|
ignore_paths = [
|
||||||
|
os.path.join(git_repo_path, '.git')
|
||||||
|
]
|
||||||
|
for ignore_path in ignore_paths:
|
||||||
|
if path.startswith(ignore_path):
|
||||||
|
return True
|
||||||
|
for component in splitall(path):
|
||||||
|
if component.startswith('.'):
|
||||||
|
return True
|
||||||
|
if component.endswith('.framework'):
|
||||||
|
return True
|
||||||
|
if component in ('Pods', 'ThirdParty', 'Carthage',):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def process_if_appropriate(filepath):
|
||||||
|
filename = os.path.basename(filepath)
|
||||||
|
if filename.startswith('.'):
|
||||||
|
return
|
||||||
|
file_ext = os.path.splitext(filename)[1]
|
||||||
|
if file_ext not in ('.h', '.hpp', '.cpp', '.m', '.mm', '.pch', '.swift'):
|
||||||
|
return
|
||||||
|
if should_ignore_path(filepath):
|
||||||
|
return
|
||||||
|
process(filepath)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='Precommit script.')
|
||||||
|
parser.add_argument('--all', action='store_true', help='process all files in or below current dir')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.all:
|
||||||
|
for rootdir, dirnames, filenames in os.walk(git_repo_path):
|
||||||
|
for filename in filenames:
|
||||||
|
file_path = os.path.abspath(os.path.join(rootdir, filename))
|
||||||
|
process_if_appropriate(file_path)
|
||||||
|
else:
|
||||||
|
filepaths = []
|
||||||
|
|
||||||
|
# Staging
|
||||||
|
output = commands.getoutput('git diff --cached --name-only --diff-filter=ACMR')
|
||||||
|
filepaths.extend([line.strip() for line in output.split('\n')])
|
||||||
|
|
||||||
|
# Working
|
||||||
|
output = commands.getoutput('git diff --name-only --diff-filter=ACMR')
|
||||||
|
filepaths.extend([line.strip() for line in output.split('\n')])
|
||||||
|
|
||||||
|
# Only process each path once.
|
||||||
|
filepaths = sorted(set(filepaths))
|
||||||
|
|
||||||
|
for filepath in filepaths:
|
||||||
|
filepath = os.path.abspath(os.path.join(git_repo_path, filepath))
|
||||||
|
process_if_appropriate(filepath)
|
@ -0,0 +1,72 @@
|
|||||||
|
//
|
||||||
|
// OWSAnalytics.h
|
||||||
|
//
|
||||||
|
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef NS_ENUM(NSUInteger, OWSAnalyticsSeverity) {
|
||||||
|
OWSAnalyticsSeverityDebug = 0,
|
||||||
|
OWSAnalyticsSeverityInfo = 1,
|
||||||
|
OWSAnalyticsSeverityWarn = 2,
|
||||||
|
OWSAnalyticsSeverityError = 3,
|
||||||
|
// I suspect we'll stage the development of our analytics,
|
||||||
|
// initially building only a minimal solution: an endpoint which
|
||||||
|
// ignores most requests, and sends only the highest-severity
|
||||||
|
// events as email to developers.
|
||||||
|
//
|
||||||
|
// This "critical" level of severity is intended for that purpose (for now).
|
||||||
|
//
|
||||||
|
// We might want to have an additional level of severity for
|
||||||
|
// critical (crashing) bugs that occur during app startup. These
|
||||||
|
// events should be sent to the service immediately and the app
|
||||||
|
// should block until that request completes.
|
||||||
|
OWSAnalyticsSeverityCritical = 4,
|
||||||
|
OWSAnalyticsSeverityOff = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is a placeholder. We don't yet serialize or transmit analytics events.
|
||||||
|
//
|
||||||
|
// If/when we take this on, we'll want to develop a solution that can be used
|
||||||
|
// report user activity - especially serious bugs - without compromising user
|
||||||
|
// privacy in any way. We must _never_ include any identifying information.
|
||||||
|
@interface OWSAnalytics : NSObject
|
||||||
|
|
||||||
|
// description: A non-empty string without any leading whitespace.
|
||||||
|
// parameters: Optional.
|
||||||
|
// If non-nil, the keys should all be non-empty NSStrings.
|
||||||
|
// Values should be NSStrings or NSNumbers.
|
||||||
|
+ (void)logEvent:(NSString *)description
|
||||||
|
severity:(OWSAnalyticsSeverity)severity
|
||||||
|
parameters:(NSDictionary *)parameters
|
||||||
|
location:(const char *)location;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#define OWSAnalyticsLogEvent(severityLevel, frmt, ...) \
|
||||||
|
[OWSAnalytics logEvent:[NSString stringWithFormat:frmt, ##__VA_ARGS__] \
|
||||||
|
severity:severityLevel \
|
||||||
|
parameters:nil \
|
||||||
|
location:__PRETTY_FUNCTION__];
|
||||||
|
|
||||||
|
#define OWSAnalyticsLogEventWithParameters(severityLevel, frmt, params) \
|
||||||
|
[OWSAnalytics logEvent:frmt severity:severityLevel parameters:params location:__PRETTY_FUNCTION__];
|
||||||
|
|
||||||
|
#define OWSAnalyticsDebug(frmt, ...) OWSAnalyticsLogEvent(OWSAnalyticsSeverityDebug, frmt, ##__VA_ARGS__)
|
||||||
|
#define OWSAnalyticsDebugWithParameters(description, params) \
|
||||||
|
OWSAnalyticsLogEventWithParameters(OWSAnalyticsSeverityDebug, description, params)
|
||||||
|
|
||||||
|
#define OWSAnalyticsInfo(frmt, ...) OWSAnalyticsLogEvent(OWSAnalyticsSeverityInfo, frmt, ##__VA_ARGS__)
|
||||||
|
#define OWSAnalyticsInfoWithParameters(description, params) \
|
||||||
|
OWSAnalyticsLogEventWithParameters(OWSAnalyticsSeverityInfo, description, params)
|
||||||
|
|
||||||
|
#define OWSAnalyticsWarn(frmt, ...) OWSAnalyticsLogEvent(OWSAnalyticsSeverityWarn, frmt, ##__VA_ARGS__)
|
||||||
|
#define OWSAnalyticsWarnWithParameters(description, params) \
|
||||||
|
OWSAnalyticsLogEventWithParameters(OWSAnalyticsSeverityWarn, description, params)
|
||||||
|
|
||||||
|
#define OWSAnalyticsError(frmt, ...) OWSAnalyticsLogEvent(OWSAnalyticsSeverityError, frmt, ##__VA_ARGS__)
|
||||||
|
#define OWSAnalyticsErrorWithParameters(description, params) \
|
||||||
|
OWSAnalyticsLogEventWithParameters(OWSAnalyticsSeverityError, description, params)
|
||||||
|
|
||||||
|
#define OWSAnalyticsCritical(frmt, ...) OWSAnalyticsLogEvent(OWSAnalyticsSeverityCritical, frmt, ##__VA_ARGS__)
|
||||||
|
#define OWSAnalyticsCriticalWithParameters(description, params) \
|
||||||
|
OWSAnalyticsLogEventWithParameters(OWSAnalyticsSeverityCritical, description, params)
|
@ -0,0 +1,76 @@
|
|||||||
|
//
|
||||||
|
// OWSAnalytics.m
|
||||||
|
//
|
||||||
|
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <CocoaLumberjack/CocoaLumberjack.h>
|
||||||
|
|
||||||
|
#import "OWSAnalytics.h"
|
||||||
|
|
||||||
|
@implementation OWSAnalytics
|
||||||
|
|
||||||
|
+ (instancetype)sharedInstance
|
||||||
|
{
|
||||||
|
static OWSAnalytics *instance = nil;
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
instance = [self new];
|
||||||
|
// TODO: If we ever log these events to disk,
|
||||||
|
// we may want to protect these file(s) like TSStorageManager.
|
||||||
|
});
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)logEvent:(NSString *)description
|
||||||
|
severity:(OWSAnalyticsSeverity)severity
|
||||||
|
parameters:(NSDictionary *)parameters
|
||||||
|
location:(const char *)location
|
||||||
|
{
|
||||||
|
|
||||||
|
[[self sharedInstance] logEvent:description severity:severity parameters:parameters location:location];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)logEvent:(NSString *)description
|
||||||
|
severity:(OWSAnalyticsSeverity)severity
|
||||||
|
parameters:(NSDictionary *)parameters
|
||||||
|
location:(const char *)location
|
||||||
|
{
|
||||||
|
|
||||||
|
DDLogFlag logFlag;
|
||||||
|
BOOL async = YES;
|
||||||
|
switch (severity) {
|
||||||
|
case OWSAnalyticsSeverityDebug:
|
||||||
|
logFlag = DDLogFlagDebug;
|
||||||
|
break;
|
||||||
|
case OWSAnalyticsSeverityInfo:
|
||||||
|
logFlag = DDLogFlagInfo;
|
||||||
|
break;
|
||||||
|
case OWSAnalyticsSeverityWarn:
|
||||||
|
logFlag = DDLogFlagWarning;
|
||||||
|
break;
|
||||||
|
case OWSAnalyticsSeverityError:
|
||||||
|
logFlag = DDLogFlagError;
|
||||||
|
async = NO;
|
||||||
|
break;
|
||||||
|
case OWSAnalyticsSeverityCritical:
|
||||||
|
logFlag = DDLogFlagError;
|
||||||
|
async = NO;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
OWSAssert(0);
|
||||||
|
logFlag = DDLogFlagDebug;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log the event.
|
||||||
|
if (!parameters) {
|
||||||
|
LOG_MAYBE(async, LOG_LEVEL_DEF, logFlag, 0, nil, location, @"%@", description);
|
||||||
|
} else {
|
||||||
|
LOG_MAYBE(async, LOG_LEVEL_DEF, logFlag, 0, nil, location, @"%@ %@", description, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do nothing. We don't yet serialize or transmit analytics events.
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
Loading…
Reference in New Issue