From e0bf1924557d84f310e7b705527ac5000a8554a4 Mon Sep 17 00:00:00 2001
From: Jonathan Harris <jonathan@marginal.org.uk>
Date: Wed, 10 Jun 2015 18:39:32 +0100
Subject: [PATCH] Add option to use a psuedo-anonymized ID in transmitted/saved
 data. Fixes #4.

---
 README.md |  3 ++-
 bpc.py    |  4 +++-
 eddn.py   |  4 +++-
 prefs.py  | 10 ++++++++++
 td.py     |  2 +-
 5 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index dc61a94b..58108fad 100644
--- a/README.md
+++ b/README.md
@@ -34,7 +34,8 @@ Setup
 --------
 The first time that you run the app you are prompted for your username and password. This is the same username and password
 combination that you use to log into the Elite: Dangerous launcher, and is required so that the Frontier servers can send the app the market data for the station that *you* are docked at.
-You can also choose here whether to send the market data that you download to EDDN, or to save it locally.
+
+You can also choose here whether to send the market data that you download to EDDN or to save it locally, and whether to attach your Cmdr name or a [pseudo-anonymized](http://en.wikipedia.org/wiki/Pseudonymity) ID to the data.
 
 You are next prompted to authenticate with a "verification code", which you will shortly receive by email from Frontier.
 Note that each "verification code" is one-time only - if you enter the code incorrectly or quit the app before
diff --git a/bpc.py b/bpc.py
index a0e58093..c1262b02 100644
--- a/bpc.py
+++ b/bpc.py
@@ -2,6 +2,7 @@
 # -*- coding: utf-8 -*-
 
 from os.path import join
+import hashlib
 import codecs
 import numbers
 import time
@@ -24,7 +25,8 @@ def export(data, csv=False):
     rowheader = '%s;%s' % (data['lastSystem']['name'].strip(), data['lastStarport']['name'].strip())
     if not csv:	# bpc
         header = 'userID;' + header
-        rowheader = '%s;%s' % (data['commander']['name'].replace(';',':').strip(), rowheader)
+        cmdr = data['commander']['name'].strip()
+        rowheader = '%s;%s' % (config.getint('anonymous') and hashlib.md5(cmdr.encode('utf-8')).hexdigest() or cmdr.replace(';',':'), rowheader)
 
     h = open(filename, 'wt')	# codecs can't automatically handle line endings, so encode manually where required
     h.write(header)
diff --git a/eddn.py b/eddn.py
index 39ba4790..00fcba50 100644
--- a/eddn.py
+++ b/eddn.py
@@ -1,6 +1,7 @@
 # Export to EDDN
 # -*- coding: utf-8 -*-
 
+import hashlib
 import json
 import numbers
 import requests
@@ -25,7 +26,8 @@ def export(data, callback):
 
     header = { 'softwareName': '%s [%s]' % (applongname, platform=='darwin' and "Mac OS" or system()),
                'softwareVersion': appversion,
-               'uploaderID': data['commander']['name'].strip() }
+               'uploaderID': config.getint('anonymous') and hashlib.md5(data['commander']['name'].strip().encode('utf-8')).hexdigest() or data['commander']['name'].strip(),
+    }
     systemName = data['lastSystem']['name'].strip()
     stationName = data['lastStarport']['name'].strip()
     timestamp = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(querytime))
diff --git a/prefs.py b/prefs.py
index 255046a3..d0b64b62 100644
--- a/prefs.py
+++ b/prefs.py
@@ -94,6 +94,15 @@ class PreferencesDialog(tk.Toplevel):
         self.outdir.grid(row=6, columnspan=2, padx=5, pady=5, sticky=tk.EW)
         self.outvarchanged()
 
+        privacyframe = ttk.LabelFrame(frame, text='Privacy')
+        privacyframe.grid(padx=10, pady=10, sticky=tk.NSEW)
+        privacyframe.columnconfigure(0, weight=1)
+
+        self.out_anon= tk.IntVar(value = config.getint('anonymous') and 1)
+        ttk.Label(privacyframe, text="How do you want to be identified in the saved data").grid(row=0, columnspan=2, padx=5, pady=3, sticky=tk.W)
+        ttk.Radiobutton(privacyframe, text="Cmdr name", variable=self.out_anon, value=0).grid(padx=5, sticky=tk.W)
+        ttk.Radiobutton(privacyframe, text="Pseudo-anonymized ID", variable=self.out_anon, value=1).grid(padx=5, pady=3, sticky=tk.W)
+
         if platform=='darwin':
             self.protocol("WM_DELETE_WINDOW", self.apply)	# close button applies changes
         else:
@@ -150,6 +159,7 @@ class PreferencesDialog(tk.Toplevel):
         config.set('password', self.password.get().strip())
         config.set('output', (self.out_eddn.get() and config.OUT_EDDN or 0) + (self.out_bpc.get() and config.OUT_BPC or 0) + (self.out_td.get() and config.OUT_TD or 0) + (self.out_csv.get() and config.OUT_CSV or 0))
         config.set('outdir', self.outdir.get().strip())
+        config.set('anonymous', self.out_anon.get())
         self.destroy()
         if credentials != (config.get('username'), config.get('password')) and self.callback:
             self.callback()
diff --git a/td.py b/td.py
index 63e9a185..5bf6fec6 100644
--- a/td.py
+++ b/td.py
@@ -30,7 +30,7 @@ def export(data):
 
     # Format described here: https://bitbucket.org/kfsone/tradedangerous/wiki/Price%20Data
     h = open(filename, 'wt')	# codecs can't automatically handle line endings, so encode manually where required
-    h.write(('#! trade.py import -\n# Created by %s %s on %s for Cmdr %s.\n#\n#    <item name>             <sellCR> <buyCR>   <demand>   <stock>  <timestamp>\n\n@ %s/%s\n' % (applongname, appversion, platform=='darwin' and "Mac OS" or system(), data['commander']['name'].strip(), data['lastSystem']['name'].strip(), data['lastStarport']['name'].strip())).encode('utf-8'))
+    h.write(('#! trade.py import -\n# Created by %s %s on %s%s.\n#\n#    <item name>             <sellCR> <buyCR>   <demand>   <stock>  <timestamp>\n\n@ %s/%s\n' % (applongname, appversion, platform=='darwin' and "Mac OS" or system(), not config.getint('anonymous') and ' for Cmdr '+data['commander']['name'].strip() or '', data['lastSystem']['name'].strip(), data['lastStarport']['name'].strip())).encode('utf-8'))
 
     # sort commodities by category
     bycategory = defaultdict(list)