Repository: rotki/rotki

Issue:
Net value over time graph for premium users
## Description

This is a premium feature. If the user has a premium subscription then they should be able to view the graph of their overall networth over time.

## Task

As this is the first premium graph/stats feature some preparatory work needs to be made:

1. Add a new pane in the UI for statistics
2. If premium is activated then that pane should load a graph of the net value of the user over time.




Discussion:

Resolving patch:
diff --git a/rotkehlchen/db/dbhandler.py b/rotkehlchen/db/dbhandler.py
--- a/rotkehlchen/db/dbhandler.py
+++ b/rotkehlchen/db/dbhandler.py
@@ -650,7 +650,7 @@ def write_balances_data(self, data: BalancesData, timestamp: Timestamp) -> None:
         per location and finally the total balance
 
         The balances are saved in the DB at the given timestamp
-"""
+        """
         balances = []
         locations = []
 
@@ -882,3 +882,20 @@ def get_rotkehlchen_premium(self) -> Optional[Tuple[str, str]]:
             return result[0]
         else:
             return None
+
+    def get_netvalue_data(self):
+        """Get all entries of net value data from the DB"""
+        cursor = self.conn.cursor()
+        result = cursor.execute(
+            'SELECT time, usd_value FROM timed_location_data '
+            'WHERE location="total" ORDER BY time ASC;',
+        )
+        result = result.fetchall()
+
+        data = []
+        times_int = []
+        for entry in result:
+            times_int.append(entry[0])
+            data.append(float(entry[1]))
+
+        return times_int, data
diff --git a/rotkehlchen/premium.py b/rotkehlchen/premium.py
--- a/rotkehlchen/premium.py
+++ b/rotkehlchen/premium.py
@@ -180,3 +180,20 @@ def query_last_data_metadata(self):
             return False, 'Could not connect to rotkehlchen server'
         success, result_or_error = _process_response(response)
         return success, result_or_error
+
+    def query_statistics_renderer(self):
+        signature, data = self.sign('statistics_renderer')
+        self.session.headers.update({
+            'API-SIGN': base64.b64encode(signature.digest()),
+        })
+
+        try:
+            response = self.session.get(
+                self.uri + 'statistics_renderer',
+                data=data,
+                timeout=ROTKEHLCHEN_SERVER_TIMEOUT,
+            )
+        except requests.ConnectionError:
+            return False, 'Could not connect to rotkehlchen server'
+        success, result_or_error = _process_response(response)
+        return success, result_or_error['data']
diff --git a/rotkehlchen/server.py b/rotkehlchen/server.py
--- a/rotkehlchen/server.py
+++ b/rotkehlchen/server.py
@@ -1,8 +1,8 @@
 # Based on https://github.com/fyears/electron-python-example
 from __future__ import print_function
 
-import os
 import logging
+import os
 import signal
 import traceback
 
@@ -208,6 +208,30 @@ def query_fiat_balances(self):
         res = self.rotkehlchen.query_fiat_balances()
         return process_result(res)
 
+    def query_netvalue_data(self):
+        res = self.rotkehlchen.data.db.get_netvalue_data()
+        result = {'times': res[0], 'data': res[1]}
+        return process_result(result)
+
+    def query_statistics_renderer(self):
+        result_dict = {'result': '', 'message': 'user does not have premium'}
+        if not self.rotkehlchen.premium:
+            return process_result(result_dict)
+
+        active, _ = self.rotkehlchen.premium.is_active()
+        if not active:
+            return process_result(result_dict)
+
+        success, result_or_error = self.rotkehlchen.premium.query_statistics_renderer()
+
+        if not success:
+            result_dict['message'] = result_or_error
+        else:
+            result_dict['result'] = result_or_error
+            result_dict['message'] = ''
+
+        return process_result(result_dict)
+
     def set_fiat_balance(self, currency: Asset, balance: str):
         result, message = self.rotkehlchen.data.set_fiat_balance(currency, balance)
         return {'result': result, 'message': message}


Test patch: