def example():
    client = StreamClient('http://localhost:8080/attask/api')
    print 'Logging in...'
    client.login('admin', 'user')
    print 'Done'

    print 'Retrieving user...'
    user = AtTaskObject(
        client.get(ObjCode.USER, client.user_id,
                   ['ID', 'homeGroupID', 'emailAddr']))
    print 'Done'
    print user

    print 'Searching projects...'
    results = client.search(ObjCode.PROJECT, {'groupID': user.homeGroupID})
    print 'Done'

    print '%s project(s) found' % len(results)
    for p in results:
        project = AtTaskObject(p)
        print ' - %s' % project.name

    print 'Creating project...'
    project = AtTaskObject(
        client.post(ObjCode.PROJECT, {
            'name': 'My Project',
            'groupID': user.homeGroupID
        }))
    print 'Done'
    print project

    print 'Retrieving project...'
    project = AtTaskObject(client.get(ObjCode.PROJECT, project.ID))
    print 'Done'
    print project

    print 'Editing project...'
    project = AtTaskObject(
        client.put(ObjCode.PROJECT, project.ID, {'ownerID': user.ID}), client)
    print 'Done'
    print project

    print 'Deleting project...'
    client.delete(ObjCode.PROJECT, project.ID)
    print 'Done'

    print 'Creating another project...'
    project = AtTaskObject({}, client)
    project.objCode = ObjCode.PROJECT
    project.name = 'My New Project'
    project.groupID = user.homeGroupID
    project.save()
    print 'Done'
    print project

    print 'Editing another project...'
    project.ownerID = user.ID
    project.save()
    print 'Done'
    print project

    print 'Deleting another project...'
    client.delete(ObjCode.PROJECT, project.ID)
    print 'Done'

    print 'Logging out...'
    client.logout()
    print 'Done'
class MoveIssues(object):
    def __init__(self, api_key: str, api_path: str, move_from: str, move_to: str, age: int):
        """
        Move Issues Init
        :param api_key: The api key for auth user
        :param api_path: Path to the api
        :param move_from: ID string of project to move tasks from
        :param move_to: ID string of project to move tasks from
        :param age: Find issues with an actual completion date greater than this value in months.
        """
        self.api_key = api_key
        self.api_path = api_path
        self.move_from = move_from
        self.move_to = move_to
        self.age = age
        # Can't bluk move more than 100 elements as per API restrictions
        self.max_results = 100
        self.completion_date_str = "$$TODAY-{age}m".format(age=self.age)
        self.client = StreamClient(self.api_path, self.api_key)

    def go(self):
        """
        Starts the moving process.
        """
        results_len = 1  # Just something to get us started
        while results_len > 0:
            issues = self.find_issues()
            results_len = len(issues)
            iss_move_count = self.move_issues(issues)
            if results_len > 0:
                results_str = "Moved {result_count} items".format(result_count=iss_move_count)
                print(results_str)

        print("Operation complete")

    def find_issues(self):
        """
        Finds issues in 'from' project to be moved.
        :return: a list of issues that meet the criteria
        """
        params = {
            "$$LIMIT": self.max_results,
            "projectID": self.move_from,
            "projectID_Mod": "in",
            "actualCompletionDate": self.completion_date_str,
            "actualCompletionDate_Mod": "lte"
        }
        fields = {}
        results = AtTaskObject(self.client.search(ObjCode.ISSUE, params, fields))
        return results.data

    def move_issues(self, data) -> int:
        """
        Moves issues between projects
        :param data: list of issues
        :return: count of issues moved
        """
        counter = 0
        for item in data:
            # Get the ID number
            uid = item['ID']
            params = {'projectID': self.move_to}
            AtTaskObject(self.client.action(ObjCode.ISSUE, 'move', params, objid=uid))
            print(".", end="", flush=True)
            counter += 1
        return counter

    def get_proj_name(self, proj_id: str):
        """
        Gets the name of a project from ID
        :param proj_id: ID number of the project to get the name of
        :return: Name of the project
        """
        results = AtTaskObject(self.client.get(ObjCode.PROJECT, proj_id))
        return results.data['name']

    def get_number_of_issues_to_move(self):
        """
        Get's a count of the number of issues to be moved
        :return: a count of the number of issues to be moved
        """
        params = {
            "projectID": self.move_from,
            "projectID_Mod": "in",
            "actualCompletionDate": self.completion_date_str,
            "actualCompletionDate_Mod": "lte"
        }
        results = AtTaskObject(self.client.report(ObjCode.ISSUE, params, 'sum'))
        return results.data['dcount_ID']