GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 40fbfa...d5d9b4 )
by Daniel
51s
created

ConnectorDB.__call__()   A

Complexity

Conditions 3

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 3
c 3
b 0
f 0
dl 0
loc 15
rs 9.4285
1
from __future__ import absolute_import
2
import json
3
import os
4
5
from ._connection import DatabaseConnection
6
7
from ._device import Device
8
from ._user import User
9
from ._stream import Stream, DATAPOINT_INSERT_LIMIT
10
11
CONNECTORDB_URL = "https://connectordb.com"
12
13
14
class ConnectorDB(Device):
15
    """ConnectorDB is the main entry point for any application that uses the python API.
16
    The class accepts both a username and password in order to log in as a user, and accepts an apikey
17
    when logging in directly from a device::
18
19
        import connectordb
20
        cdb = connectordb.ConnectorDB("myusername","mypassword")
21
22
        #prints "myusername/user" - logging in by username/password combo
23
        #logs in as the user device.
24
        print cdb.path
25
26
    """
27
28
    def __init__(self, user_or_apikey=None, user_password=None, url=CONNECTORDB_URL):
29
30
        db = DatabaseConnection(user_or_apikey, user_password, url)
31
32
        # ConnectorDB uses bcrypt by default for password hashing. While great for security
33
        # of passwords, it is extremely expensive, so it slows down queries. So, if we logged in
34
        # as a user with password, attempt to get the user device apikey to use for future authentication
35
        # so that queries are fast
36
        if user_password is not None:
37
            # Logins happen as a user device
38
            Device.__init__(self, db, user_or_apikey + "/user")
39
40
            if self.apikey is not None:
41
                # Reset the auth to be apikey
42
                db.setauth(self.apikey)
43
        else:
44
            # We logged in as a device - we have to ping the server to get our
45
            # name
46
            Device.__init__(self, db, db.path)
47
48
    def __call__(self, path):
49
        """Enables getting arbitrary users/devices/streams in a simple way. Just call the object
50
        with the u/d/s uri
51
            cdb = ConnectorDB("myapikey")
52
            cdb("user1") -> user1 object
53
            cdb("user1/device1") -> user1/device1 object
54
            cdb("user1/device1/stream1") -> user1/device1/stream1 object
55
        """
56
        n = path.count("/")
57
        if n == 0:
58
            return User(self.db, path)
59
        elif n == 1:
60
            return Device(self.db, path)
61
        else:
62
            return Stream(self.db, path)
63
64
    def close(self):
65
        """shuts down all active connections to ConnectorDB"""
66
        self.db.close()
67
68
    def reset_apikey(self):
69
        """invalidates the device's current api key, and generates a new one. Resets current auth to use the new apikey,
70
        since the change would have future queries fail if they use the old api key."""
71
        apikey = Device.reset_apikey(self)
72
        self.db.setauth(apikey)
73
        return apikey
74
75
    def count_users(self):
76
        """Gets the total number of users registered with the database. Only available to administrator."""
77
        return int(self.db.get("", {"q": "countusers"}).text)
78
79
    def count_devices(self):
80
        """Gets the total number of devices registered with the database. Only available to administrator."""
81
        return int(self.db.get("", {"q": "countdevices"}).text)
82
83
    def count_streams(self):
84
        """Gets the total number of streams registered with the database. Only available to administrator."""
85
        return int(self.db.get("", {"q": "countstreams"}).text)
86
87
    def info(self):
88
        """returns a dictionary of information about the database, including the database version, the transforms
89
        and the interpolators supported::
90
91
            >>>cdb = connectordb.ConnectorDB(apikey)
92
            >>>cdb.info()
93
            {
94
                "version": "0.3.0",
95
                "transforms": {
96
                    "sum": {"description": "Returns the sum of all the datapoints that go through the transform"}
97
                    ...
98
                },
99
                "interpolators": {
100
                    "closest": {"description": "Uses the datapoint closest to the interpolation timestamp"}
101
                    ...
102
                }
103
            }
104
105
        """
106
        return {
107
            "version": self.db.get("meta/version").text,
108
            "transforms": self.db.get("meta/transforms").json(),
109
            "interpolators": self.db.get("meta/interpolators").json()
110
        }
111
112
    def __repr__(self):
113
        return "[ConnectorDB:%s]" % (self.path, )
114
115
    def users(self):
116
        """Returns the list of users in the database"""
117
        result = self.db.read("", {"q": "ls"})
118
119
        if result is None or result.json() is None:
120
            return []
121
        users = []
122
        for u in result.json():
123
            usr = self(u["name"])
124
            usr.metadata = u
125
            users.append(usr)
126
        return users
127
128
    def ping(self):
129
        """Pings the ConnectorDB server. Useful for checking if the connection is valid"""
130
        return self.db.ping()
131
132
    def import_users(self, directory):
133
        """Imports version 1 of ConnectorDB export. These exports can be generated
134
        by running user.export(dir), possibly on multiple users.
135
        """
136
        exportInfoFile = os.path.join(directory, "connectordb.json")
137
        with open(exportInfoFile) as f:
138
            exportInfo = json.load(f)
139
        if exportInfo["Version"] != 1:
140
            raise ValueError("Not able to read this import version")
141
142
        # Now we list all the user directories
143
        for name in os.listdir(directory):
144
            udir = os.path.join(directory, name)
145
            if os.path.isdir(udir):
146
                # Let's read in the user
147
                with open(os.path.join(udir, "user.json")) as f:
148
                    usrdata = json.load(f)
149
150
                u = self(usrdata["name"])
151
                if u.exists():
152
                    raise ValueError("The user " + name + " already exists")
153
154
                del usrdata["name"]
155
                u.create(password=name, **usrdata)
156
157
                # Now read all of the user's devices
158
                for dname in os.listdir(udir):
159
                    ddir = os.path.join(udir, dname)
160
                    if os.path.isdir(ddir):
161
                        u.import_device(ddir)
162