""" Python library for interacting with Project Vote Smart API.

    Project Vote Smart's API (http://www.votesmart.org/services_api.php)
    provides rich biographical data, including data on votes, committee
    assignments, and much more.
"""

__author__ = "James Turk <jturk@sunlightfoundation.com>"
__version__ = "0.3.2"
__copyright__ = "Copyright (c) 2009 Sunlight Labs"
__license__ = "BSD"

import urllib, urllib2
try:
    import json
except ImportError:
    import simplejson as json

class VotesmartApiError(Exception):
    """ Exception for Sunlight API errors """

class VotesmartApiObject(object):
    def __init__(self, d):
        self.__dict__ = d

    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__, self.__dict__)

class Address(object):
    def __init__(self, d):
        self.__dict__.update(d['address'])
        self.__dict__.update(d['phone'])
        self.__dict__.update(d['notes'])

    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__, self.__dict__)

class WebAddress(VotesmartApiObject):
    def __str__(self):
        return self.webAddress

class Bio(object):
    def __init__(self, d):
        #self.__dict__.update(d['election'])
        #self.__dict__.update(d['office'])
        self.__dict__.update(d['candidate'])

    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__, self.__dict__)

class AddlBio(VotesmartApiObject):
    def __str__(self):
        return ': '.join((self.name, self.data))

class Candidate(VotesmartApiObject):
    def __str__(self):
        return ' '.join((self.firstName, self.lastName))

class CommitteeType(VotesmartApiObject):
    def __str__(self):
        return self.name

class Committee(VotesmartApiObject):
    def __str__(self):
        return self.name

class CommitteeDetail(VotesmartApiObject):
    def __str__(self):
        return self.name

class CommitteeMember(VotesmartApiObject):
    def __str__(self):
        return ' '.join((self.title, self.firstName, self.lastName))

class District(VotesmartApiObject):
    def __str__(self):
        return self.name

class Election(VotesmartApiObject):
    def __init__(self, d):
        stages = d.pop('stage', None)
        self.__dict__ = d
        if stages:
            self.stages = _result_to_obj(ElectionStage, stages)

    def __str__(self):
        return self.name

class ElectionStage(VotesmartApiObject):
    def __str__(self):
        return '%s (%s)' % (self.name, self.electionDate)

class Official(VotesmartApiObject):
    def __str__(self):
        return ' '.join((self.title, self.firstName, self.lastName))

class LeadershipPosition(VotesmartApiObject):
    def __str__(self):
        return self.name

class Locality(VotesmartApiObject):
    def __str__(self):
        return self.name

class Measure(VotesmartApiObject):
    def __str__(self):
        return self.title

class MeasureDetail(VotesmartApiObject):
    def __str__(self):
        return self.title

class OfficeType(VotesmartApiObject):
    def __str__(self):
        return ': '.join((self.officeTypeId, self.name))

class OfficeBranch(VotesmartApiObject):
    def __str__(self):
        return ': '.join((self.officeBranchId, self.name))

class OfficeLevel(VotesmartApiObject):
    def __str__(self):
        return ': '.join((self.officeLevelId, self.name))

class Office(VotesmartApiObject):
    def __str__(self):
        return self.name

class Category(VotesmartApiObject):
    def __str__(self):
        return ': '.join((self.categoryId, self.name))

class Sig(VotesmartApiObject):
    def __str__(self):
        return ': '.join((self.sigId, self.name))

class SigDetail(VotesmartApiObject):
    def __str__(self):
        return self.name

class Rating(VotesmartApiObject):
    def __str__(self):
        return self.ratingText

class State(VotesmartApiObject):
    def __str__(self):
        return ' '.join((self.stateId, self.name))

class StateDetail(VotesmartApiObject):
    def __str__(self):
        return ' '.join((self.stateId, self.name))

class BillSponsor(VotesmartApiObject):
    def __str__(self):
        return self.name

class BillAction(VotesmartApiObject):
    def __str__(self):
        return ' - '.join((self.statusDate, self.stage))

class BillAmendment(VotesmartApiObject):
    def __str__(self):
        return self.title

class BillDetail(VotesmartApiObject):
    def __init__(self, d):
        sponsors = d.pop('sponsors')
        actions = d.pop('actions')
        amendments = d.pop('amendments')  # ammendments -- sic
        self.sponsors = _result_to_obj(BillSponsor, sponsors['sponsor'])
        self.actions = _result_to_obj(BillAction, actions['action'])
        if amendments:
            self.amendments = _result_to_obj(BillAmendment, amendments['amendment'])
        self.__dict__.update(d)

class BillActionDetail(VotesmartApiObject):
    def __str__(self):
        return self.officialTitle

class Bill(VotesmartApiObject):
    def __str__(self):
        return ' '.join((self.billNumber, self.title))

class Vote(VotesmartApiObject):
    def __str__(self):
        return ': '.join((self.candidateName, self.action))

class Veto(VotesmartApiObject):
    def __str__(self):
        return ' '.join((self.billNumber, self.billTitle))

def _result_to_obj(cls, result):
    if isinstance(result, dict):
        return [cls(result)]
    else:
        # the if o predicate is important, sometimes they return empty strings
        return [cls(o) for o in result if o]

class votesmart(object):

    apikey = None

    @staticmethod
    def _apicall(func, params):
        if votesmart.apikey is None:
            raise VotesmartApiError('Missing Project Vote Smart apikey')

        params = dict([(k,v) for (k,v) in params.iteritems() if v])
        url = 'http://api.votesmart.org/%s?o=JSON&key=%s&%s' % (func,
            votesmart.apikey, urllib.urlencode(params))
        try:
            response = urllib2.urlopen(url).read()
            obj = json.loads(response)
            if 'error' in obj:
                raise VotesmartApiError(obj['error']['errorMessage'])
            else:
                return obj
        except urllib2.HTTPError, e:
            raise VotesmartApiError(e)
        except ValueError, e:
            raise VotesmartApiError('Invalid Response')

    class address(object):
        @staticmethod
        def getCampaign(candidateId):
            params = {'candidateId': candidateId}
            result = votesmart._apicall('Address.getCampaign', params)
            return _result_to_obj(Address, result['address']['office'])

        @staticmethod
        def getCampaignWebAddress(candidateId):
            params = {'candidateId': candidateId}
            result = votesmart._apicall('Address.getCampaignWebAddress', params)
            return _result_to_obj(WebAddress, result['webaddress']['address'])

        @staticmethod
        def getCampaignByElection(electionId):
            params = {'electionId': electionId}
            result = votesmart._apicall('Address.getCampaignByElection', params)
            return _result_to_obj(Address, result['address']['office'])

        @staticmethod
        def getOffice(candidateId):
            params = {'candidateId': candidateId}
            result = votesmart._apicall('Address.getOffice', params)
            return _result_to_obj(Address, result['address']['office'])

        @staticmethod
        def getOfficeWebAddress(candidateId):
            params = {'candidateId': candidateId}
            result = votesmart._apicall('Address.getOfficeWebAddress', params)
            return _result_to_obj(WebAddress, result['webaddress']['address'])

        #@staticmethod
        #def getOfficeByOfficeState(officeId, stateId=None):
        #    params = {'officeId': officeId, 'stateId': stateId}
        #    result = votesmart._apicall('Address.getOfficeByOfficeState', params)
        #    return _result_to_obj(Address, result['address']['office'])

    class candidatebio(object):
        @staticmethod
        def getBio(candidateId):
            params = {'candidateId': candidateId}
            result = votesmart._apicall('CandidateBio.getBio', params)
            return Bio(result['bio'])

        @staticmethod
        def getAddlBio(candidateId):
            params = {'candidateId': candidateId}
            result = votesmart._apicall('CandidateBio.getAddlBio', params)
            return _result_to_obj(AddlBio,
                                  result['addlBio']['additional']['item'])

    class candidates(object):
        @staticmethod
        def getByOfficeState(officeId, stateId=None, electionYear=None):
            params = {'officeId': officeId, 'stateId':stateId, 'electionYear': electionYear}
            result = votesmart._apicall('Candidates.getByOfficeState', params)
            return _result_to_obj(Candidate, result['candidateList']['candidate'])

        @staticmethod
        def getByOfficeTypeState(officeTypeId, stateId=None, electionYear=None):
            params = {'officeTypeId': officeTypeId, 'stateId':stateId, 'electionYear': electionYear}
            result = votesmart._apicall('Candidates.getByOfficeTypeState', params)
            return _result_to_obj(Candidate, result['candidateList']['candidate'])

        @staticmethod
        def getByLastname(lastName, electionYear=None):
            params = {'lastName': lastName, 'electionYear':electionYear}
            result = votesmart._apicall('Candidates.getByLastname', params)
            return _result_to_obj(Candidate, result['candidateList']['candidate'])

        @staticmethod
        def getByLevenstein(lastName, electionYear=None):
            params = {'lastName': lastName, 'electionYear':electionYear}
            result = votesmart._apicall('Candidates.getByLevenstein', params)
            return _result_to_obj(Candidate, result['candidateList']['candidate'])

        @staticmethod
        def getByElection(electionId):
            params = {'electionId': electionId}
            result = votesmart._apicall('Candidates.getByElection', params)
            return _result_to_obj(Candidate, result['candidateList']['candidate'])

        @staticmethod
        def getByDistrict(districtId, electionYear=None):
            params = {'districtId': districtId, 'electionYear':electionYear}
            result = votesmart._apicall('Candidates.getByDistrict', params)
            return _result_to_obj(Candidate, result['candidateList']['candidate'])

        @staticmethod
        def getByZip(zip5, zip4=None):
            params = {'zip4': zip4, 'zip5': zip5}
            result = votesmart._apicall('Candidates.getByZip', params)
            return _result_to_obj(Candidate, result['candidateList']['candidate'])

    class committee(object):
        @staticmethod
        def getTypes():
            result = votesmart._apicall('Committee.getTypes', {})
            return _result_to_obj(CommitteeType, result['committeeTypes']['type'])

        @staticmethod
        def getCommitteesByTypeState(typeId=None, stateId=None):
            params = {'typeId':typeId, 'stateId':stateId}
            result = votesmart._apicall('Committee.getCommitteesByTypeState', params)
            return _result_to_obj(Committee, result['committees']['committee'])

        @staticmethod
        def getCommittee(committeeId):
            params = {'committeeId' : committeeId}
            result = votesmart._apicall('Committee.getCommittee', params)
            return CommitteeDetail(result['committee'])

        @staticmethod
        def getCommitteeMembers(committeeId):
            params = {'committeeId' : committeeId}
            result = votesmart._apicall('Committee.getCommitteeMembers', params)
            return _result_to_obj(CommitteeMember, result['committeeMembers']['member'])

    class district(object):
        @staticmethod
        def getByOfficeState(officeId, stateId, districtName=None):
            params = {'officeId':officeId, 'stateId': stateId, 'districtName': districtName}
            result = votesmart._apicall('District.getByOfficeState', params)
            return _result_to_obj(District, result['districtList']['district'])

        @staticmethod
        def getByZip(zip5, zip4=None):
            params = {'zip5': zip5, 'zip4': zip4}
            result = votesmart._apicall('District.getByZip', params)
            return _result_to_obj(District, result['districtList']['district'])

    class election(object):
        @staticmethod
        def getElection(electionId):
            params = {'electionId':electionId}
            result = votesmart._apicall('Election.getElection', params)
            return Election(result['elections']['election'])

        @staticmethod
        def getElectionByYearState(year, stateId=None):
            params = {'year':year, 'stateId':stateId}
            result = votesmart._apicall('Election.getElectionByYearState', params)
            return _result_to_obj(Election, result['elections']['election'])

        @staticmethod
        def getElectionByZip(zip5, zip4=None, year=None):
            params = {'zip5': zip5, 'zip4': zip4, 'year': year}
            result = votesmart._apicall('Election.getElectionByZip', params)
            return _result_to_obj(Election, result['elections']['election'])

        @staticmethod
        def getStageCandidates(electionId, stageId, party=None,
                               districtId=None, stateId=None):
            params = {'electionId':electionId, 'stageId':stageId,
                      'party':party, 'districtId':districtId, 'stateId':stateId}
            result = votesmart._apicall('Election.getStageCandidates', params)
            return _result_to_obj(Candidate, result['stageCandidates']['candidate'])

    class leadership(object):
        @staticmethod
        def getPositions(stateId=None, officeId=None):
            params = {'stateId':stateId, 'officeId':officeId}
            result = votesmart._apicall('Leadership.getPositions', params)
            return _result_to_obj(LeadershipPosition, result['leadership']['position'])

        #@staticmethod
        #def getCandidates(leadershipId, stateId=None):
        #    params = {'leadershipId':leadershipId, 'stateId':stateId}
        #    result = votesmart._apicall('Leadership.getCandidates', params)
        #    return result['leaders']['leader']

    class local(object):
        @staticmethod
        def getCounties(stateId):
            params = {'stateId': stateId}
            result = votesmart._apicall('Local.getCounties', params)
            return _result_to_obj(Locality, result['counties']['county'])

        @staticmethod
        def getCities(stateId):
            params = {'stateId': stateId}
            result = votesmart._apicall('Local.getCities', params)
            return _result_to_obj(Locality, result['cities']['city'])

        @staticmethod
        def getOfficials(localId):
            params = {'localId': localId}
            result = votesmart._apicall('Local.getOfficials', params)
            return _result_to_obj(Official, result['candidateList']['candidate'])

    class measure(object):
        @staticmethod
        def getMeasuresByYearState(year, stateId):
            params = {'year':year, 'stateId':stateId}
            result = votesmart._apicall('Measure.getMeasuresByYearState', params)
            return _result_to_obj(Measure, result['measures']['measure'])

        @staticmethod
        def getMeasure(measureId):
            params = {'measureId':measureId}
            result = votesmart._apicall('Measure.getMeasure', params)
            return MeasureDetail(result['measure'])

    class npat(object):
        @staticmethod
        def getNpat(candidateId):
            params = {'candidateId':candidateId}
            result = votesmart._apicall('Npat.getNpat', params)
            return result['npat']

    class office(object):
        @staticmethod
        def getTypes():
            result = votesmart._apicall('Office.getTypes', {})
            return _result_to_obj(OfficeType, result['officeTypes']['type'])

        @staticmethod
        def getBranches():
            result = votesmart._apicall('Office.getBranches', {})
            return _result_to_obj(OfficeBranch, result['branches']['branch'])

        @staticmethod
        def getLevels():
            result = votesmart._apicall('Office.getLevels', {})
            return _result_to_obj(OfficeLevel, result['levels']['level'])

        @staticmethod
        def getOfficesByType(typeId):
            params = {'typeId':typeId}
            result = votesmart._apicall('Office.getOfficesByType', params)
            return _result_to_obj(Office, result['offices']['office'])

        @staticmethod
        def getOfficesByLevel(levelId):
            params = {'levelId':levelId}
            result = votesmart._apicall('Office.getOfficesByLevel', params)
            return _result_to_obj(Office, result['offices']['office'])

        @staticmethod
        def getOfficesByTypeLevel(typeId, levelId):
            params = {'typeId':typeId, 'levelId':levelId}
            result = votesmart._apicall('Office.getOfficesByTypeLevel', params)
            return _result_to_obj(Office, result['offices']['office'])

        @staticmethod
        def getOfficesByBranchLevel(branchId, levelId):
            params = {'branchId':branchId, 'levelId':levelId}
            result = votesmart._apicall('Office.getOfficesByBranchLevel', params)
            return _result_to_obj(Office, result['offices']['office'])

    class officials(object):
        @staticmethod
        def getStatewide(stateId=None):
            params = {'stateId': stateId}
            result = votesmart._apicall('Officials.getStatewide', params)
            return _result_to_obj(Official, result['candidateList']['candidate'])

        @staticmethod
        def getByOfficeState(officeId, stateId=None):
            params = {'officeId':officeId, 'stateId': stateId}
            result = votesmart._apicall('Officials.getByOfficeState', params)
            return _result_to_obj(Official, result['candidateList']['candidate'])

        @staticmethod
        def getByLastname(lastName):
            params = {'lastName':lastName}
            result = votesmart._apicall('Officials.getByLastname', params)
            return _result_to_obj(Official, result['candidateList']['candidate'])

        @staticmethod
        def getByLevenstein(lastName):
            params = {'lastName':lastName}
            result = votesmart._apicall('Officials.getByLevenstein', params)
            return _result_to_obj(Official, result['candidateList']['candidate'])

        @staticmethod
        def getByElection(electionId):
            params = {'electionId':electionId}
            result = votesmart._apicall('Officials.getByElection', params)
            return _result_to_obj(Official, result['candidateList']['candidate'])

        @staticmethod
        def getByDistrict(districtId):
            params = {'districtId':districtId}
            result = votesmart._apicall('Officials.getByDistrict', params)
            return _result_to_obj(Official, result['candidateList']['candidate'])

        @staticmethod
        def getByZip(zip5, zip4=None):
            params = {'zip4': zip4, 'zip5': zip5}
            result = votesmart._apicall('Officials.getByZip', params)
            return _result_to_obj(Official, result['candidateList']['candidate'])

    class rating(object):
        @staticmethod
        def getCategories(stateId=None):
            params = {'stateId':stateId}
            result = votesmart._apicall('Rating.getCategories', params)
            return _result_to_obj(Category, result['categories']['category'])

        @staticmethod
        def getSigList(categoryId, stateId=None):
            params = {'categoryId':categoryId, 'stateId':stateId}
            result = votesmart._apicall('Rating.getSigList', params)
            return _result_to_obj(Sig, result['sigs']['sig'])

        @staticmethod
        def getSig(sigId):
            params = {'sigId':sigId}
            result = votesmart._apicall('Rating.getSig', params)
            return SigDetail(result['sig'])

        @staticmethod
        def getCandidateRating(candidateId, sigId):
            params = {'candidateId':candidateId, 'sigId':sigId}
            result = votesmart._apicall('Rating.getCandidateRating', params)
            return _result_to_obj(Rating, result['candidateRating']['rating'])

    class state(object):
        @staticmethod
        def getStateIDs():
            result = votesmart._apicall('State.getStateIDs', {})
            return _result_to_obj(State, result['stateList']['list']['state'])

        @staticmethod
        def getState(stateId):
            params = {'stateId':stateId}
            result = votesmart._apicall('State.getState', params)
            return StateDetail(result['state']['details'])

    class votes(object):
        @staticmethod
        def getCategories(year, stateId=None):
            params = {'year':year, 'stateId':stateId}
            result = votesmart._apicall('Votes.getCategories', params)
            return _result_to_obj(Category, result['categories']['category'])

        @staticmethod
        def getBill(billId):
            params = {'billId':billId}
            result = votesmart._apicall('Votes.getBill', params)
            return BillDetail(result['bill'])

        @staticmethod
        def getBillAction(actionId):
            params = {'actionId':actionId}
            result = votesmart._apicall('Votes.getBillAction', params)
            return BillActionDetail(result['action'])

        @staticmethod
        def getBillActionVotes(actionId):
            params = {'actionId':actionId}
            result = votesmart._apicall('Votes.getBillActionVotes', params)
            return _result_to_obj(Vote, result['votes']['vote'])

        @staticmethod
        def getBillActionVoteByOfficial(actionId, candidateId):
            params = {'actionId':actionId, 'candidateId':candidateId}
            result = votesmart._apicall('Votes.getBillActionVoteByOfficial', params)
            return Vote(result['votes']['vote'])

        @staticmethod
        def getByBillNumber(billNumber):
            params = {'billNumber': billNumber}
            result = votesmart._apicall('Votes.getByBillNumber', params)
            return _result_to_obj(Bill, result['bills']['bill'])

        @staticmethod
        def getBillsByCategoryYearState(categoryId, year, stateId=None):
            params = {'categoryId':categoryId, 'year':year, 'stateId':stateId}
            result = votesmart._apicall('Votes.getBillsByCategoryYearState', params)
            return _result_to_obj(Bill, result['bills']['bill'])

        @staticmethod
        def getBillsByYearState(year, stateId=None):
            params = {'year':year, 'stateId':stateId}
            result = votesmart._apicall('Votes.getBillsByYearState', params)
            return _result_to_obj(Bill, result['bills']['bill'])

        @staticmethod
        def getBillsByOfficialYearOffice(candidateId, year, officeId=None):
            params = {'candidateId':candidateId, 'year':year, 'officeId':officeId}
            result = votesmart._apicall('Votes.getBillsByOfficialYearOffice', params)
            return _result_to_obj(Bill, result['bills']['bill'])

        @staticmethod
        def getBillsByCandidateCategoryOffice(candidateId, categoryId, officeId=None):
            params = {'candidateId':candidateId, 'categoryId':categoryId, 'officeId':officeId}
            result = votesmart._apicall('Votes.getBillsByCandidateCategoryOffice', params)
            return _result_to_obj(Bill, result['bills']['bill'])

        @staticmethod
        def getBillsBySponsorYear(candidateId, year):
            params = {'candidateId':candidateId, 'year':year}
            result = votesmart._apicall('Votes.getBillsBySponsorYear', params)
            return _result_to_obj(Bill, result['bills']['bill'])

        @staticmethod
        def getBillsBySponsorCategory(candidateId, categoryId):
            params = {'candidateId':candidateId, 'categoryId':categoryId}
            result = votesmart._apicall('Votes.getBillsBySponsorCategory', params)
            return _result_to_obj(Bill, result['bills']['bill'])

        @staticmethod
        def getBillsByStateRecent(stateId=None, amount=None):
            params = {'stateId':stateId, 'amount':amount}
            result = votesmart._apicall('Votes.getBillsByStateRecent', params)
            return _result_to_obj(Bill, result['bills']['bill'])

        @staticmethod
        def getVetoes(candidateId):
            params = {'candidateId': candidateId}
            result = votesmart._apicall('Votes.getVetoes', params)
            return _result_to_obj(Veto, result['vetoes']['veto'])

""" Python library for interacting with Project Vote Smart API.

    Project Vote Smart's API (http://www.votesmart.org/services_api.php)
    provides rich biographical data, including data on votes, committee
    assignments, and much more.
"""

__author__ = "James Turk <jturk@sunlightfoundation.com>"
__version__ = "0.3.2"
__copyright__ = "Copyright (c) 2009 Sunlight Labs"
__license__ = "BSD"

import urllib, urllib2
try:
    import json
except ImportError:
    import simplejson as json

class VotesmartApiError(Exception):
    """ Exception for Sunlight API errors """

class VotesmartApiObject(object):
    def __init__(self, d):
        self.__dict__ = d

    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__, self.__dict__)

class Address(object):
    def __init__(self, d):
        self.__dict__.update(d['address'])
        self.__dict__.update(d['phone'])
        self.__dict__.update(d['notes'])

    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__, self.__dict__)

class WebAddress(VotesmartApiObject):
    def __str__(self):
        return self.webAddress

class Bio(object):
    def __init__(self, d):
        #self.__dict__.update(d['election'])
        #self.__dict__.update(d['office'])
        self.__dict__.update(d['candidate'])

    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__, self.__dict__)

class AddlBio(VotesmartApiObject):
    def __str__(self):
        return ': '.join((self.name, self.data))

class Candidate(VotesmartApiObject):
    def __str__(self):
        return ' '.join((self.firstName, self.lastName))

class CommitteeType(VotesmartApiObject):
    def __str__(self):
        return self.name

class Committee(VotesmartApiObject):
    def __str__(self):
        return self.name

class CommitteeDetail(VotesmartApiObject):
    def __str__(self):
        return self.name

class CommitteeMember(VotesmartApiObject):
    def __str__(self):
        return ' '.join((self.title, self.firstName, self.lastName))

class District(VotesmartApiObject):
    def __str__(self):
        return self.name

class Election(VotesmartApiObject):
    def __init__(self, d):
        stages = d.pop('stage', None)
        self.__dict__ = d
        if stages:
            self.stages = _result_to_obj(ElectionStage, stages)

    def __str__(self):
        return self.name

class ElectionStage(VotesmartApiObject):
    def __str__(self):
        return '%s (%s)' % (self.name, self.electionDate)

class Official(VotesmartApiObject):
    def __str__(self):
        return ' '.join((self.title, self.firstName, self.lastName))

class LeadershipPosition(VotesmartApiObject):
    def __str__(self):
        return self.name

class Locality(VotesmartApiObject):
    def __str__(self):
        return self.name

class Measure(VotesmartApiObject):
    def __str__(self):
        return self.title

class MeasureDetail(VotesmartApiObject):
    def __str__(self):
        return self.title

class OfficeType(VotesmartApiObject):
    def __str__(self):
        return ': '.join((self.officeTypeId, self.name))

class OfficeBranch(VotesmartApiObject):
    def __str__(self):
        return ': '.join((self.officeBranchId, self.name))

class OfficeLevel(VotesmartApiObject):
    def __str__(self):
        return ': '.join((self.officeLevelId, self.name))

class Office(VotesmartApiObject):
    def __str__(self):
        return self.name

class Category(VotesmartApiObject):
    def __str__(self):
        return ': '.join((self.categoryId, self.name))

class Sig(VotesmartApiObject):
    def __str__(self):
        return ': '.join((self.sigId, self.name))

class SigDetail(VotesmartApiObject):
    def __str__(self):
        return self.name

class Rating(VotesmartApiObject):
    def __str__(self):
        return self.ratingText

class State(VotesmartApiObject):
    def __str__(self):
        return ' '.join((self.stateId, self.name))

class StateDetail(VotesmartApiObject):
    def __str__(self):
        return ' '.join((self.stateId, self.name))

class BillSponsor(VotesmartApiObject):
    def __str__(self):
        return self.name

class BillAction(VotesmartApiObject):
    def __str__(self):
        return ' - '.join((self.statusDate, self.stage))

class BillAmendment(VotesmartApiObject):
    def __str__(self):
        return self.title

class BillDetail(VotesmartApiObject):
    def __init__(self, d):
        sponsors = d.pop('sponsors')
        actions = d.pop('actions')
        amendments = d.pop('amendments')  # ammendments -- sic
        self.sponsors = _result_to_obj(BillSponsor, sponsors['sponsor'])
        self.actions = _result_to_obj(BillAction, actions['action'])
        if amendments:
            self.amendments = _result_to_obj(BillAmendment, amendments['amendment'])
        self.__dict__.update(d)

class BillActionDetail(VotesmartApiObject):
    def __str__(self):
        return self.officialTitle

class Bill(VotesmartApiObject):
    def __str__(self):
        return ' '.join((self.billNumber, self.title))

class Vote(VotesmartApiObject):
    def __str__(self):
        return ': '.join((self.candidateName, self.action))

class Veto(VotesmartApiObject):
    def __str__(self):
        return ' '.join((self.billNumber, self.billTitle))

def _result_to_obj(cls, result):
    if isinstance(result, dict):
        return [cls(result)]
    else:
        # the if o predicate is important, sometimes they return empty strings
        return [cls(o) for o in result if o]

class votesmart(object):

    apikey = None

    @staticmethod
    def _apicall(func, params):
        if votesmart.apikey is None:
            raise VotesmartApiError('Missing Project Vote Smart apikey')

        params = dict([(k,v) for (k,v) in params.iteritems() if v])
        url = 'http://api.votesmart.org/%s?o=JSON&key=%s&%s' % (func,
            votesmart.apikey, urllib.urlencode(params))
        try:
            response = urllib2.urlopen(url).read()
            obj = json.loads(response)
            if 'error' in obj:
                raise VotesmartApiError(obj['error']['errorMessage'])
            else:
                return obj
        except urllib2.HTTPError, e:
            raise VotesmartApiError(e)
        except ValueError, e:
            raise VotesmartApiError('Invalid Response')

    class address(object):
        @staticmethod
        def getCampaign(candidateId):
            params = {'candidateId': candidateId}
            result = votesmart._apicall('Address.getCampaign', params)
            return _result_to_obj(Address, result['address']['office'])

        @staticmethod
        def getCampaignWebAddress(candidateId):
            params = {'candidateId': candidateId}
            result = votesmart._apicall('Address.getCampaignWebAddress', params)
            return _result_to_obj(WebAddress, result['webaddress']['address'])

        @staticmethod
        def getCampaignByElection(electionId):
            params = {'electionId': electionId}
            result = votesmart._apicall('Address.getCampaignByElection', params)
            return _result_to_obj(Address, result['address']['office'])

        @staticmethod
        def getOffice(candidateId):
            params = {'candidateId': candidateId}
            result = votesmart._apicall('Address.getOffice', params)
            return _result_to_obj(Address, result['address']['office'])

        @staticmethod
        def getOfficeWebAddress(candidateId):
            params = {'candidateId': candidateId}
            result = votesmart._apicall('Address.getOfficeWebAddress', params)
            return _result_to_obj(WebAddress, result['webaddress']['address'])

        #@staticmethod
        #def getOfficeByOfficeState(officeId, stateId=None):
        #    params = {'officeId': officeId, 'stateId': stateId}
        #    result = votesmart._apicall('Address.getOfficeByOfficeState', params)
        #    return _result_to_obj(Address, result['address']['office'])

    class candidatebio(object):
        @staticmethod
        def getBio(candidateId):
            params = {'candidateId': candidateId}
            result = votesmart._apicall('CandidateBio.getBio', params)
            return Bio(result['bio'])

        @staticmethod
        def getAddlBio(candidateId):
            params = {'candidateId': candidateId}
            result = votesmart._apicall('CandidateBio.getAddlBio', params)
            return _result_to_obj(AddlBio,
                                  result['addlBio']['additional']['item'])

    class candidates(object):
        @staticmethod
        def getByOfficeState(officeId, stateId=None, electionYear=None):
            params = {'officeId': officeId, 'stateId':stateId, 'electionYear': electionYear}
            result = votesmart._apicall('Candidates.getByOfficeState', params)
            return _result_to_obj(Candidate, result['candidateList']['candidate'])

        @staticmethod
        def getByOfficeTypeState(officeTypeId, stateId=None, electionYear=None):
            params = {'officeTypeId': officeTypeId, 'stateId':stateId, 'electionYear': electionYear}
            result = votesmart._apicall('Candidates.getByOfficeTypeState', params)
            return _result_to_obj(Candidate, result['candidateList']['candidate'])

        @staticmethod
        def getByLastname(lastName, electionYear=None):
            params = {'lastName': lastName, 'electionYear':electionYear}
            result = votesmart._apicall('Candidates.getByLastname', params)
            return _result_to_obj(Candidate, result['candidateList']['candidate'])

        @staticmethod
        def getByLevenstein(lastName, electionYear=None):
            params = {'lastName': lastName, 'electionYear':electionYear}
            result = votesmart._apicall('Candidates.getByLevenstein', params)
            return _result_to_obj(Candidate, result['candidateList']['candidate'])

        @staticmethod
        def getByElection(electionId):
            params = {'electionId': electionId}
            result = votesmart._apicall('Candidates.getByElection', params)
            return _result_to_obj(Candidate, result['candidateList']['candidate'])

        @staticmethod
        def getByDistrict(districtId, electionYear=None):
            params = {'districtId': districtId, 'electionYear':electionYear}
            result = votesmart._apicall('Candidates.getByDistrict', params)
            return _result_to_obj(Candidate, result['candidateList']['candidate'])

        @staticmethod
        def getByZip(zip5, zip4=None):
            params = {'zip4': zip4, 'zip5': zip5}
            result = votesmart._apicall('Candidates.getByZip', params)
            return _result_to_obj(Candidate, result['candidateList']['candidate'])

    class committee(object):
        @staticmethod
        def getTypes():
            result = votesmart._apicall('Committee.getTypes', {})
            return _result_to_obj(CommitteeType, result['committeeTypes']['type'])

        @staticmethod
        def getCommitteesByTypeState(typeId=None, stateId=None):
            params = {'typeId':typeId, 'stateId':stateId}
            result = votesmart._apicall('Committee.getCommitteesByTypeState', params)
            return _result_to_obj(Committee, result['committees']['committee'])

        @staticmethod
        def getCommittee(committeeId):
            params = {'committeeId' : committeeId}
            result = votesmart._apicall('Committee.getCommittee', params)
            return CommitteeDetail(result['committee'])

        @staticmethod
        def getCommitteeMembers(committeeId):
            params = {'committeeId' : committeeId}
            result = votesmart._apicall('Committee.getCommitteeMembers', params)
            return _result_to_obj(CommitteeMember, result['committeeMembers']['member'])

    class district(object):
        @staticmethod
        def getByOfficeState(officeId, stateId, districtName=None):
            params = {'officeId':officeId, 'stateId': stateId, 'districtName': districtName}
            result = votesmart._apicall('District.getByOfficeState', params)
            return _result_to_obj(District, result['districtList']['district'])

        @staticmethod
        def getByZip(zip5, zip4=None):
            params = {'zip5': zip5, 'zip4': zip4}
            result = votesmart._apicall('District.getByZip', params)
            return _result_to_obj(District, result['districtList']['district'])

    class election(object):
        @staticmethod
        def getElection(electionId):
            params = {'electionId':electionId}
            result = votesmart._apicall('Election.getElection', params)
            return Election(result['elections']['election'])

        @staticmethod
        def getElectionByYearState(year, stateId=None):
            params = {'year':year, 'stateId':stateId}
            result = votesmart._apicall('Election.getElectionByYearState', params)
            return _result_to_obj(Election, result['elections']['election'])

        @staticmethod
        def getElectionByZip(zip5, zip4=None, year=None):
            params = {'zip5': zip5, 'zip4': zip4, 'year': year}
            result = votesmart._apicall('Election.getElectionByZip', params)
            return _result_to_obj(Election, result['elections']['election'])

        @staticmethod
        def getStageCandidates(electionId, stageId, party=None,
                               districtId=None, stateId=None):
            params = {'electionId':electionId, 'stageId':stageId,
                      'party':party, 'districtId':districtId, 'stateId':stateId}
            result = votesmart._apicall('Election.getStageCandidates', params)
            return _result_to_obj(Candidate, result['stageCandidates']['candidate'])

    class leadership(object):
        @staticmethod
        def getPositions(stateId=None, officeId=None):
            params = {'stateId':stateId, 'officeId':officeId}
            result = votesmart._apicall('Leadership.getPositions', params)
            return _result_to_obj(LeadershipPosition, result['leadership']['position'])

        #@staticmethod
        #def getCandidates(leadershipId, stateId=None):
        #    params = {'leadershipId':leadershipId, 'stateId':stateId}
        #    result = votesmart._apicall('Leadership.getCandidates', params)
        #    return result['leaders']['leader']

    class local(object):
        @staticmethod
        def getCounties(stateId):
            params = {'stateId': stateId}
            result = votesmart._apicall('Local.getCounties', params)
            return _result_to_obj(Locality, result['counties']['county'])

        @staticmethod
        def getCities(stateId):
            params = {'stateId': stateId}
            result = votesmart._apicall('Local.getCities', params)
            return _result_to_obj(Locality, result['cities']['city'])

        @staticmethod
        def getOfficials(localId):
            params = {'localId': localId}
            result = votesmart._apicall('Local.getOfficials', params)
            return _result_to_obj(Official, result['candidateList']['candidate'])

    class measure(object):
        @staticmethod
        def getMeasuresByYearState(year, stateId):
            params = {'year':year, 'stateId':stateId}
            result = votesmart._apicall('Measure.getMeasuresByYearState', params)
            return _result_to_obj(Measure, result['measures']['measure'])

        @staticmethod
        def getMeasure(measureId):
            params = {'measureId':measureId}
            result = votesmart._apicall('Measure.getMeasure', params)
            return MeasureDetail(result['measure'])

    class npat(object):
        @staticmethod
        def getNpat(candidateId):
            params = {'candidateId':candidateId}
            result = votesmart._apicall('Npat.getNpat', params)
            return result['npat']

    class office(object):
        @staticmethod
        def getTypes():
            result = votesmart._apicall('Office.getTypes', {})
            return _result_to_obj(OfficeType, result['officeTypes']['type'])

        @staticmethod
        def getBranches():
            result = votesmart._apicall('Office.getBranches', {})
            return _result_to_obj(OfficeBranch, result['branches']['branch'])

        @staticmethod
        def getLevels():
            result = votesmart._apicall('Office.getLevels', {})
            return _result_to_obj(OfficeLevel, result['levels']['level'])

        @staticmethod
        def getOfficesByType(typeId):
            params = {'typeId':typeId}
            result = votesmart._apicall('Office.getOfficesByType', params)
            return _result_to_obj(Office, result['offices']['office'])

        @staticmethod
        def getOfficesByLevel(levelId):
            params = {'levelId':levelId}
            result = votesmart._apicall('Office.getOfficesByLevel', params)
            return _result_to_obj(Office, result['offices']['office'])

        @staticmethod
        def getOfficesByTypeLevel(typeId, levelId):
            params = {'typeId':typeId, 'levelId':levelId}
            result = votesmart._apicall('Office.getOfficesByTypeLevel', params)
            return _result_to_obj(Office, result['offices']['office'])

        @staticmethod
        def getOfficesByBranchLevel(branchId, levelId):
            params = {'branchId':branchId, 'levelId':levelId}
            result = votesmart._apicall('Office.getOfficesByBranchLevel', params)
            return _result_to_obj(Office, result['offices']['office'])

    class officials(object):
        @staticmethod
        def getStatewide(stateId=None):
            params = {'stateId': stateId}
            result = votesmart._apicall('Officials.getStatewide', params)
            return _result_to_obj(Official, result['candidateList']['candidate'])

        @staticmethod
        def getByOfficeState(officeId, stateId=None):
            params = {'officeId':officeId, 'stateId': stateId}
            result = votesmart._apicall('Officials.getByOfficeState', params)
            return _result_to_obj(Official, result['candidateList']['candidate'])

        @staticmethod
        def getByLastname(lastName):
            params = {'lastName':lastName}
            result = votesmart._apicall('Officials.getByLastname', params)
            return _result_to_obj(Official, result['candidateList']['candidate'])

        @staticmethod
        def getByLevenstein(lastName):
            params = {'lastName':lastName}
            result = votesmart._apicall('Officials.getByLevenstein', params)
            return _result_to_obj(Official, result['candidateList']['candidate'])

        @staticmethod
        def getByElection(electionId):
            params = {'electionId':electionId}
            result = votesmart._apicall('Officials.getByElection', params)
            return _result_to_obj(Official, result['candidateList']['candidate'])

        @staticmethod
        def getByDistrict(districtId):
            params = {'districtId':districtId}
            result = votesmart._apicall('Officials.getByDistrict', params)
            return _result_to_obj(Official, result['candidateList']['candidate'])

        @staticmethod
        def getByZip(zip5, zip4=None):
            params = {'zip4': zip4, 'zip5': zip5}
            result = votesmart._apicall('Officials.getByZip', params)
            return _result_to_obj(Official, result['candidateList']['candidate'])

    class rating(object):
        @staticmethod
        def getCategories(stateId=None):
            params = {'stateId':stateId}
            result = votesmart._apicall('Rating.getCategories', params)
            return _result_to_obj(Category, result['categories']['category'])

        @staticmethod
        def getSigList(categoryId, stateId=None):
            params = {'categoryId':categoryId, 'stateId':stateId}
            result = votesmart._apicall('Rating.getSigList', params)
            return _result_to_obj(Sig, result['sigs']['sig'])

        @staticmethod
        def getSig(sigId):
            params = {'sigId':sigId}
            result = votesmart._apicall('Rating.getSig', params)
            return SigDetail(result['sig'])

        @staticmethod
        def getCandidateRating(candidateId, sigId=None):
            params = {'candidateId':candidateId, 'sigId':sigId}
            result = votesmart._apicall('Rating.getCandidateRating', params)
            return _result_to_obj(Rating, result['candidateRating']['rating'])

    class state(object):
        @staticmethod
        def getStateIDs():
            result = votesmart._apicall('State.getStateIDs', {})
            return _result_to_obj(State, result['stateList']['list']['state'])

        @staticmethod
        def getState(stateId):
            params = {'stateId':stateId}
            result = votesmart._apicall('State.getState', params)
            return StateDetail(result['state']['details'])

    class votes(object):
        @staticmethod
        def getCategories(year, stateId=None):
            params = {'year':year, 'stateId':stateId}
            result = votesmart._apicall('Votes.getCategories', params)
            return _result_to_obj(Category, result['categories']['category'])

        @staticmethod
        def getBill(billId):
            params = {'billId':billId}
            result = votesmart._apicall('Votes.getBill', params)
            return BillDetail(result['bill'])

        @staticmethod
        def getBillAction(actionId):
            params = {'actionId':actionId}
            result = votesmart._apicall('Votes.getBillAction', params)
            return BillActionDetail(result['action'])

        @staticmethod
        def getBillActionVotes(actionId):
            params = {'actionId':actionId}
            result = votesmart._apicall('Votes.getBillActionVotes', params)
            return _result_to_obj(Vote, result['votes']['vote'])

        @staticmethod
        def getBillActionVoteByOfficial(actionId, candidateId):
            params = {'actionId':actionId, 'candidateId':candidateId}
            result = votesmart._apicall('Votes.getBillActionVoteByOfficial', params)
            return Vote(result['votes']['vote'])

        @staticmethod
        def getByBillNumber(billNumber):
            params = {'billNumber': billNumber}
            result = votesmart._apicall('Votes.getByBillNumber', params)
            return _result_to_obj(Bill, result['bills']['bill'])

        @staticmethod
        def getBillsByCategoryYearState(categoryId, year, stateId=None):
            params = {'categoryId':categoryId, 'year':year, 'stateId':stateId}
            result = votesmart._apicall('Votes.getBillsByCategoryYearState', params)
            return _result_to_obj(Bill, result['bills']['bill'])

        @staticmethod
        def getBillsByYearState(year, stateId=None):
            params = {'year':year, 'stateId':stateId}
            result = votesmart._apicall('Votes.getBillsByYearState', params)
            return _result_to_obj(Bill, result['bills']['bill'])

        @staticmethod
        def getBillsByOfficialYearOffice(candidateId, year, officeId=None):
            params = {'candidateId':candidateId, 'year':year, 'officeId':officeId}
            result = votesmart._apicall('Votes.getBillsByOfficialYearOffice', params)
            return _result_to_obj(Bill, result['bills']['bill'])

        @staticmethod
        def getBillsByCandidateCategoryOffice(candidateId, categoryId, officeId=None):
            params = {'candidateId':candidateId, 'categoryId':categoryId, 'officeId':officeId}
            result = votesmart._apicall('Votes.getBillsByCandidateCategoryOffice', params)
            return _result_to_obj(Bill, result['bills']['bill'])

        @staticmethod
        def getBillsBySponsorYear(candidateId, year):
            params = {'candidateId':candidateId, 'year':year}
            result = votesmart._apicall('Votes.getBillsBySponsorYear', params)
            return _result_to_obj(Bill, result['bills']['bill'])

        @staticmethod
        def getBillsBySponsorCategory(candidateId, categoryId):
            params = {'candidateId':candidateId, 'categoryId':categoryId}
            result = votesmart._apicall('Votes.getBillsBySponsorCategory', params)
            return _result_to_obj(Bill, result['bills']['bill'])

        @staticmethod
        def getBillsByStateRecent(stateId=None, amount=None):
            params = {'stateId':stateId, 'amount':amount}
            result = votesmart._apicall('Votes.getBillsByStateRecent', params)
            return _result_to_obj(Bill, result['bills']['bill'])

        @staticmethod
        def getVetoes(candidateId):
            params = {'candidateId': candidateId}
            result = votesmart._apicall('Votes.getVetoes', params)
            return _result_to_obj(Veto, result['vetoes']['veto'])


from setuptools import setup, find_packages
import sys, os

version = '2.0'
shortdesc = "LDAP convenience library"
longdesc = open(os.path.join(os.path.dirname(__file__), 'README.rst')).read()
longdesc += open(os.path.join(os.path.dirname(__file__), 'LICENSE.rst')).read()

setup(name='bda.ldap',
      version=version,
      description=shortdesc,
      long_description=longdesc,
      classifiers=[
            'Development Status :: 4 - Beta',
            'Environment :: Web Environment',
            'Framework :: Zope2',
            'License :: OSI Approved :: GNU General Public License (GPL)',
            'Operating System :: OS Independent',
            'Programming Language :: Python',
            'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
      ], # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
      keywords='',
      author='BlueDynamics Alliance',
      author_email='dev@bluedynamics.com',
      url='https://svn.plone.org/svn/collective/bda.ldap',
      license='General Public Licence',
      packages=find_packages('src'),
      package_dir = {'': 'src'},
      namespace_packages=['bda'],
      include_package_data=True,
      zip_safe=False,
      install_requires=[
          'setuptools',
          'python-ldap',
          'zodict',
          'bda.cache',
      ],
      extras_require={
          'test': [
              'interlude',
              'plone.testing',
              'unittest2',
              'zope.configuration',
              'zope.testing',
          ]
      },
      entry_points="""
      [console_scripts]
      testldap = bda.ldap.main:slapd
      """,
      )

from setuptools import setup, find_packages
import sys, os

version = '2.0'
shortdesc = "LDAP convenience library"
longdesc = open(os.path.join(os.path.dirname(__file__), 'README.rst')).read()
longdesc += open(os.path.join(os.path.dirname(__file__), 'LICENSE.rst')).read()

setup(name='bda.ldap',
      version=version,
      description=shortdesc,
      long_description=longdesc,
      classifiers=[
            'Development Status :: 4 - Beta',
            'Environment :: Web Environment',
            'Framework :: Zope2',
            'License :: OSI Approved :: GNU General Public License (GPL)',
            'Operating System :: OS Independent',
            'Programming Language :: Python',
            'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
      ], # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
      keywords='',
      author='BlueDynamics Alliance',
      author_email='dev@bluedynamics.com',
      url='https://github.com/bluedynamics/bda.ldap',
      license='General Public Licence',
      packages=find_packages('src'),
      package_dir = {'': 'src'},
      namespace_packages=['bda'],
      include_package_data=True,
      zip_safe=False,
      install_requires=[
          'setuptools',
          'python-ldap',
          'zodict',
          'bda.cache',
      ],
      extras_require={
          'test': [
              'interlude',
              'plone.testing',
              'unittest2',
              'zope.configuration',
              'zope.testing',
          ]
      },
      entry_points="""
      [console_scripts]
      testldap = bda.ldap.main:slapd
      """,
      )


# Licensed to Cloudera, Inc. under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  Cloudera, Inc. licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from setuptools import setup, find_packages

setup(
      name = "about",
      version = "0.9",
      author = "Hue",
      url = 'http://github.com/cloudera/hue',
      description = "Displays 'about' info for easier trouble-shooting",
      packages = find_packages('src'),
      package_dir = {'': 'src'},
      install_requires = ['setuptools', 'desktop'],
      entry_points = { 'desktop.sdk.application': 'about=about' },
)

# Licensed to Cloudera, Inc. under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  Cloudera, Inc. licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from setuptools import setup, find_packages
from hueversion import VERSION

setup(
      name = "about",
      version = VERSION,
      author = "Hue",
      url = 'http://github.com/cloudera/hue',
      description = "Displays 'about' info for easier trouble-shooting",
      packages = find_packages('src'),
      package_dir = {'': 'src'},
      install_requires = ['setuptools', 'desktop'],
      entry_points = { 'desktop.sdk.application': 'about=about' },
)


require "yaml"
require "erb"

# A simple settings solution using a YAML file. See README for more information.
class Settingslogic < Hash
  class MissingSetting < StandardError; end

  class << self

    def source(value = nil)
      if value.nil?
        @source
      else
        @source = value
      end
    end

    def namespace(value = nil)
      if value.nil?
        @namespace
      else
        @namespace = value
      end
    end

    def default_namespace(value = nil)
      if value.nil?
        @default_namespace || 'defaults'
      else
        @default_namespace = value
      end
    end

    def key_by_path(key_path, separator = ".")
      # Settings.get_nested_key('some.nested.setting')
      tmp = instance
      key_path.split(separator).each do |k|
        if tmp[k].respond_to?("[]") && !tmp[k].nil?
          tmp = tmp[k]
        else
          return nil
        end
      end
      tmp
    end

    def [](key)
      # Setting.key.value or Setting[:key][:value] or Setting['key']['value']
      fetch(key.to_s,nil)
    end

    def []=(key,val)
      # Setting[:key] = 'value' for dynamic settings
      store(key.to_s,val)
    end

    def load!
      instance
      true
    end

    def reload!
      @instance = nil
      load!
    end

    private
      def instance
        @instance ||= new
      end

      def method_missing(name, *args, &block)
        instance.send(name, *args, &block)
      end
  end

  # Initializes a new settings object. You can initialize an object in any of the following ways:
  #
  #   Settings.new(:application) # will look for config/application.yml
  #   Settings.new("application.yaml") # will look for application.yaml
  #   Settings.new("/var/configs/application.yml") # will look for /var/configs/application.yml
  #   Settings.new(:config1 => 1, :config2 => 2)
  #
  # Basically if you pass a symbol it will look for that file in the configs directory of your rails app,
  # if you are using this in rails. If you pass a string it should be an absolute path to your settings file.
  # Then you can pass a hash, and it just allows you to access the hash via methods.
  def initialize(hash_or_file = self.class.source, section = nil)
    case hash_or_file
    when Hash
      self.replace hash_or_file
    else
      hash = YAML.load(ERB.new(File.read(hash_or_file)).result).to_hash
      default_hash = hash[self.class.default_namespace] || {}
      hash = hash[self.class.namespace] if self.class.namespace
      self.replace default_hash.deep_merge(hash)
    end
    @section = section || hash_or_file  # so end of error says "in application.yml"
    create_accessors!
  end

  # Called for dynamically-defined keys, and also the first key deferenced at the top-level, if load! is not used.
  # Otherwise, create_accessors! (called by new) will have created actual methods for each key.
  def method_missing(key, *args, &block)
    begin
      value = fetch(key.to_s)
    rescue IndexError
      raise MissingSetting, "Missing setting '#{key}' in #{@section}"
    end
    value.is_a?(Hash) ? self.class.new(value, "'#{key}' section in #{@section}") : value
  end

  private
    # This handles naming collisions with Sinatra/Vlad/Capistrano. Since these use a set()
    # helper that defines methods in Object, ANY method_missing ANYWHERE picks up the Vlad/Sinatra
    # settings!  So settings.deploy_to title actually calls Object.deploy_to (from set :deploy_to, "host"),
    # rather than the app_yml['deploy_to'] hash.  Jeezus.
    def create_accessors!
      self.each do |key,val|
        # Use instance_eval/class_eval because they're actually more efficient than define_method{}
        # http://stackoverflow.com/questions/185947/ruby-definemethod-vs-def
        # http://bmorearty.wordpress.com/2009/01/09/fun-with-rubys-instance_eval-and-class_eval/
        self.class.class_eval <<-EndEval
          def #{key}
            return @#{key} if @#{key}  # cache (performance)
            value = fetch('#{key}')
            @#{key} = value.is_a?(Hash) ? self.class.new(value, "'#{key}' section in #{@section}") : value
          end
        EndEval
      end
    end

end

require "yaml"
require "erb"

# A simple settings solution using a YAML file. See README for more information.
class Settingslogic < Hash
  class MissingSetting < StandardError; end

  class << self

    def source(value = nil)
      if value.nil?
        @source
      else
        @source = value
      end
    end

    def namespace(value = nil)
      if value.nil?
        @namespace
      else
        @namespace = value
      end
    end

    def default_namespace(value = nil)
      if value.nil?
        @default_namespace || 'defaults'
      else
        @default_namespace = value
      end
    end

    def key_by_path(key_path, separator = ".")
      # Settings.get_nested_key('some.nested.setting')
      tmp = instance
      key_path.split(separator).each do |k|
        if tmp[k].respond_to?("[]") && !tmp[k].nil?
          tmp = tmp[k]
        else
          return nil
        end
      end
      tmp
    end

    def [](key)
      # Setting.key.value or Setting[:key][:value] or Setting['key']['value']
      fetch(key.to_s,nil)
    end

    def []=(key,val)
      # Setting[:key] = 'value' for dynamic settings
      store(key.to_s,val)
    end

    def load!
      instance
      true
    end

    def reload!
      @instance = nil
      load!
    end

    private
      def instance
        @instance ||= new
      end

      def method_missing(name, *args, &block)
        instance.send(name, *args, &block)
      end
  end

  # Initializes a new settings object. You can initialize an object in any of the following ways:
  #
  #   Settings.new(:application) # will look for config/application.yml
  #   Settings.new("application.yaml") # will look for application.yaml
  #   Settings.new("/var/configs/application.yml") # will look for /var/configs/application.yml
  #   Settings.new(:config1 => 1, :config2 => 2)
  #
  # Basically if you pass a symbol it will look for that file in the configs directory of your rails app,
  # if you are using this in rails. If you pass a string it should be an absolute path to your settings file.
  # Then you can pass a hash, and it just allows you to access the hash via methods.
  def initialize(hash_or_file = self.class.source, section = nil)
    case hash_or_file
    when Hash
      self.replace hash_or_file
    else
      hash = YAML.load(ERB.new(File.read(hash_or_file)).result).to_hash
      default_hash = hash[self.class.default_namespace] || {}
      hash = hash[self.class.namespace] if self.class.namespace
      self.replace default_hash.deep_merge(hash)
    end
    @section = section || hash_or_file  # so end of error says "in application.yml"
    create_accessors!
  end

  def [](key)
    # @settings.key.value or @settings[:key][:value] or @settings['key']['value']
    super(key.to_s)
  end

  # Called for dynamically-defined keys, and also the first key deferenced at the top-level, if load! is not used.
  # Otherwise, create_accessors! (called by new) will have created actual methods for each key.
  def method_missing(key, *args, &block)
    begin
      value = fetch(key.to_s)
    rescue IndexError
      raise MissingSetting, "Missing setting '#{key}' in #{@section}"
    end
    value.is_a?(Hash) ? self.class.new(value, "'#{key}' section in #{@section}") : value
  end

  private
    # This handles naming collisions with Sinatra/Vlad/Capistrano. Since these use a set()
    # helper that defines methods in Object, ANY method_missing ANYWHERE picks up the Vlad/Sinatra
    # settings!  So settings.deploy_to title actually calls Object.deploy_to (from set :deploy_to, "host"),
    # rather than the app_yml['deploy_to'] hash.  Jeezus.
    def create_accessors!
      self.each do |key,val|
        unless key.to_s.first.to_i.to_s == key.to_s.first # key.first.digit?
          # Use instance_eval/class_eval because they're actually more efficient than define_method{}
          # http://stackoverflow.com/questions/185947/ruby-definemethod-vs-def
          # http://bmorearty.wordpress.com/2009/01/09/fun-with-rubys-instance_eval-and-class_eval/
          self.class.class_eval <<-EndEval
            def #{key}
              return @#{key} if @#{key}  # cache (performance)
              value = fetch('#{key}')
              @#{key} = value.is_a?(Hash) ? self.class.new(value, "'#{key}' section in #{@section}") : value
            end
          EndEval
        end
      end
    end

end


package main

import (
	"bytes"
	"encoding/csv"
	"github.com/bmizerany/assert"
	"io/ioutil"
	"log"
	"os"
	"testing"
)

func TestGetTopic(t *testing.T) {
	log.SetOutput(ioutil.Discard)
	defer log.SetOutput(os.Stdout)

	reader := bytes.NewBufferString(`{"a": 1, "b": "asdf\n"}
{"a" : null}`)
	buf := bytes.NewBuffer([]byte{})
	writer := csv.NewWriter(buf)

	json2csv(reader, writer, []string{"a", "c"}, false)

	output := buf.String()
	assert.Equal(t, output, "1,\n,\n")
}

func TestGetLargeInt(t *testing.T) {
	log.SetOutput(ioutil.Discard)
	defer log.SetOutput(os.Stdout)

	reader := bytes.NewBufferString(`{"a": 1356998399}`)
	buf := bytes.NewBuffer([]byte{})
	writer := csv.NewWriter(buf)

	json2csv(reader, writer, []string{"a"}, false)

	output := buf.String()
	assert.Equal(t, output, "1356998399\n")
}

func TestGetFloat(t *testing.T) {
	log.SetOutput(ioutil.Discard)
	defer log.SetOutput(os.Stdout)

	reader := bytes.NewBufferString(`{"a": 1356998399.32}`)
	buf := bytes.NewBuffer([]byte{})
	writer := csv.NewWriter(buf)

	json2csv(reader, writer, []string{"a"}, false)

	output := buf.String()
	assert.Equal(t, output, "1356998399.320000\n")
}

func TestGetNested(t *testing.T) {
	log.SetOutput(ioutil.Discard)
	defer log.SetOutput(os.Stdout)

	reader := bytes.NewBufferString(`{"a": {"b": "asdf"}}`)
	buf := bytes.NewBuffer([]byte{})
	writer := csv.NewWriter(buf)

	json2csv(reader, writer, []string{"a.b"}, false)

	output := buf.String()
	assert.Equal(t, output, "asdf\n")
}

func TestHeader(t *testing.T) {
	log.SetOutput(ioutil.Discard)
	defer log.SetOutput(os.Stdout)

	reader := bytes.NewBufferString(`{"a": "b"}
{"a": "c"}`)
	buf := bytes.NewBuffer([]byte{})
	writer := csv.NewWriter(buf)

	json2csv(reader, writer, []string{"a"}, true)

	output := buf.String()
	assert.Equal(t, output, "a\nb\nc\n")
}

package main

import (
	"bytes"
	"encoding/csv"
	"io/ioutil"
	"log"
	"os"
	"testing"

	"github.com/bmizerany/assert"
)

func TestGetTopic(t *testing.T) {
	log.SetOutput(ioutil.Discard)
	defer log.SetOutput(os.Stdout)

	reader := bytes.NewBufferString(`{"a": 1, "b": "asdf\n"}
{"a" : null}`)
	buf := bytes.NewBuffer([]byte{})
	writer := csv.NewWriter(buf)

	json2csv(reader, writer, []string{"a", "c"}, false)

	output := buf.String()
	assert.Equal(t, output, "1,\n,\n")
}

func TestGetLargeInt(t *testing.T) {
	log.SetOutput(ioutil.Discard)
	defer log.SetOutput(os.Stdout)

	reader := bytes.NewBufferString(`{"a": 1356998399}`)
	buf := bytes.NewBuffer([]byte{})
	writer := csv.NewWriter(buf)

	json2csv(reader, writer, []string{"a"}, false)

	output := buf.String()
	assert.Equal(t, output, "1356998399\n")
}

func TestGetFloat(t *testing.T) {
	log.SetOutput(ioutil.Discard)
	defer log.SetOutput(os.Stdout)

	reader := bytes.NewBufferString(`{"a": 1356998399.32}`)
	buf := bytes.NewBuffer([]byte{})
	writer := csv.NewWriter(buf)

	json2csv(reader, writer, []string{"a"}, false)

	output := buf.String()
	assert.Equal(t, output, "1356998399.320000\n")
}

func TestGetNested(t *testing.T) {
	log.SetOutput(ioutil.Discard)
	defer log.SetOutput(os.Stdout)

	reader := bytes.NewBufferString(`{"a": {"b": "asdf"}}`)
	buf := bytes.NewBuffer([]byte{})
	writer := csv.NewWriter(buf)

	json2csv(reader, writer, []string{"a.b"}, false)

	output := buf.String()
	assert.Equal(t, output, "asdf\n")
}

func TestHeader(t *testing.T) {
	log.SetOutput(ioutil.Discard)
	defer log.SetOutput(os.Stdout)

	reader := bytes.NewBufferString(`{"a": "b"}
{"a": "c"}`)
	buf := bytes.NewBuffer([]byte{})
	writer := csv.NewWriter(buf)

	json2csv(reader, writer, []string{"a"}, true)

	output := buf.String()
	assert.Equal(t, output, "a\nb\nc\n")
}


<!DOCTYPE html>

    <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
    <meta name="keywords" content="rsvndump, rsvndump homepage, Subversion, dump, remote, backup">
    <link href="stylesheet.css" rel="stylesheet" type="text/css">

    <title>rsvndump - remote Subversion repository dump</title>

rsvndump - remote Subversion repository dump

About

News

Content

About

rsvndump is a command line tool that is able to dump a
        Subversion repository that resides on a remote server.
        All data is dumped in the format that can be read an written by
        svnadmin load/dump, so the data which is produced
        can easily be imported into a new Subversion repository.

rsvndump supports most of the functionality of the normal
        svn client program and svnadmin, e.g. authentication,
        SSL-support, incremental dumps and support for dumping text
        deltas instead of full text.

Starting with Subversion 1.7 in October 2011, the official distribution already
        contains a remote dumpfile tool
        called svnrdump.  While both tools serve the same purpose,
        rsvndump is also able to dump a subdirectory of a repository by
        resolving copy operations as needed, even without read access to
        the repository root. Furthermore, rsvndump may work better with
        old Subversion servers (i.e. versions prior to 1.5).

Further information about rsvndump's behavior and possible
        differences to the output generated by svnadmin dump
        and svnrdump can be found at the man page.

News

February 15th, 2022

rsvndump 0.6.1 is now available, fixing a
          bug where sub-directories which matching prefixes would be included in
          the dump () and improving the autoconf setup. Many thanks to @hartwork
          and @wmbaum for their contributions!

May 14th, 2012

rsvndump 0.6 is now available,
          offering new features and fixing several bugs. The version
          path and property storages have been redesigned, resulting
          in a notable speedup for certain use cases. An issue that could have
          led to unloadable dumps when dumping subdirectories has been resolved.
          Furthermore, revision range handling in incremental mode and a build system issue
          (#3515292)
          have been fixed.

          The full list of changes can be found in the
          ChangeLog. As usual, the source package is
          is available as a tarball compressed using either gzip or bzip2 as
          well as in zip format.

March 11th, 2012

rsvndump 0.5.8 is now available,
          fixing two serious bugs reported by Valentin Haenel
          (#3483858 and
          #3489637).
          Both issues could result in invalid dump output
          under certain circumstances.  Please consult the
          ChangeLog and the respective bug reports
          for further details about those issues.

          As usual, the source package is is available as a tarball
          compressed using either gzip or bzip2 as well as in zip
          format.

November 21st, 2011

rsvndump 0.5.7 is now available,
          fixing possibly invalid dump output when run with
          <tt>--keep-revnums</tt>.  Furthermore, the command-line flags
          <tt>--dry-run</tt> and <tt>--obfuscate</tt> have been added
          to ease the submission of dumps for bug reports. A build
          system fix from Sebastian Pipping has been applied as well
          (#3369622).
          The full list of changes can be found in the
          ChangeLog. As usual, the source package is
          is available as a tarball compressed using either gzip or bzip2 as
          well as in zip format.

July 15th, 2011

rsvndump 0.5.6 is now available. This
          release includes performance improvements for revision range
          determination and path hash calculations. A bug that could cause
          unloadable dumps under certain conditions as well as a possible
          segmentation fault have been fixed. The CodeBlocks project file
          for Compilation on Windows has been fixed, too.
          The full list of changes can be found in the
          ChangeLog. As usual, the source package is
          is available as a tarball compressed using either gzip or bzip2 as
          well as in zip format.

I've recently set up a Flattr
          account and added an entry for rsvndump.
          So if you like the program, please feel free to flattr it :)

March 3rd, 2011

rsvndump 0.5.5 is now available. This
          release fixes a bug introduced in 0.5.3
          (#2997558)
          which could led to crashes when dumping a
          subdirectory. Additionally, performance issues caused by
          unnecessary stats for copied revisions have been fixed. The
          full list of changes can be found in the
          ChangeLog. As usual, the source package is
          is available as a tarball compressed using either gzip or bzip2 as
          well as in zip format.

Older news items can be found in the news archive.

Content

Downloads:

rsvndump-0.6.1.tar.gz - Source code distribution

rsvndump-0.6.1.tar.bz2 - Source code distribution

rsvndump-0.6.1.zip - Source code distribution

Previous releases can be found on rsvndump's file list at SourceForge.

Distribution packages/ports:

NOTE: These are not maintained by myself. Thanks go out to the respective packagers!

ArchLinux (AUR)

Fedora

FreeBSD

Gentoo

openSUSE

... and others

Documentation:

README - Requirements and general information

README.win32 - Build instructions for Windows

man page - Online version of the man page

ChangeLog - The rsvndump change log

COPYING - The GPL v3, under which rsvndump is released

Hosted:

The Git repository with issue tracker at GitHub

The project page at SourceForge

The project page at Freshmeat

The project page at Ohloh

The thing page at Flattr for
                micropayment donations

Jonas Gehring
          Last update: $DATE

<!DOCTYPE html>

    <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
    <meta name="keywords" content="rsvndump, rsvndump homepage, Subversion, dump, remote, backup">
    <link href="stylesheet.css" rel="stylesheet" type="text/css">

    <title>rsvndump - remote Subversion repository dump</title>

rsvndump - remote Subversion repository dump

About

News

Content

About

rsvndump is a command line tool that is able to dump a
        Subversion repository that resides on a remote server.
        All data is dumped in the format that can be read an written by
        svnadmin load/dump, so the data which is produced
        can easily be imported into a new Subversion repository.

rsvndump supports most of the functionality of the normal
        svn client program and svnadmin, e.g. authentication,
        SSL-support, incremental dumps and support for dumping text
        deltas instead of full text.

Starting with Subversion 1.7 in October 2011, the official distribution already
        contains a remote dumpfile tool
        called svnrdump.  While both tools serve the same purpose,
        rsvndump is also able to dump a subdirectory of a repository by
        resolving copy operations as needed, even without read access to
        the repository root. Furthermore, rsvndump may work better with
        old Subversion servers (i.e. versions prior to 1.5).

Further information about rsvndump's behavior and possible
        differences to the output generated by svnadmin dump
        and svnrdump can be found at the man page.

News

February 15th, 2022

rsvndump 0.6.1 is now available, fixing a
          bug where sub-directories which matching prefixes would be included in
          the dump () and improving the autoconf setup. Many thanks to @hartwork
          and @wmbaum for their contributions!

May 14th, 2012

rsvndump 0.6 is now available,
          offering new features and fixing several bugs. The version
          path and property storages have been redesigned, resulting
          in a notable speedup for certain use cases. An issue that could have
          led to unloadable dumps when dumping subdirectories has been resolved.
          Furthermore, revision range handling in incremental mode and a build system issue
          (#3515292)
          have been fixed.

          The full list of changes can be found in the
          ChangeLog. As usual, the source package is
          is available as a tarball compressed using either gzip or bzip2 as
          well as in zip format.

March 11th, 2012

rsvndump 0.5.8 is now available,
          fixing two serious bugs reported by Valentin Haenel
          (#3483858 and
          #3489637).
          Both issues could result in invalid dump output
          under certain circumstances.  Please consult the
          ChangeLog and the respective bug reports
          for further details about those issues.

          As usual, the source package is is available as a tarball
          compressed using either gzip or bzip2 as well as in zip
          format.

November 21st, 2011

rsvndump 0.5.7 is now available,
          fixing possibly invalid dump output when run with
          <tt>--keep-revnums</tt>.  Furthermore, the command-line flags
          <tt>--dry-run</tt> and <tt>--obfuscate</tt> have been added
          to ease the submission of dumps for bug reports. A build
          system fix from Sebastian Pipping has been applied as well
          (#3369622).
          The full list of changes can be found in the
          ChangeLog. As usual, the source package is
          is available as a tarball compressed using either gzip or bzip2 as
          well as in zip format.

July 15th, 2011

rsvndump 0.5.6 is now available. This
          release includes performance improvements for revision range
          determination and path hash calculations. A bug that could cause
          unloadable dumps under certain conditions as well as a possible
          segmentation fault have been fixed. The CodeBlocks project file
          for Compilation on Windows has been fixed, too.
          The full list of changes can be found in the
          ChangeLog. As usual, the source package is
          is available as a tarball compressed using either gzip or bzip2 as
          well as in zip format.

March 3rd, 2011

rsvndump 0.5.5 is now available. This
          release fixes a bug introduced in 0.5.3
          (#2997558)
          which could led to crashes when dumping a
          subdirectory. Additionally, performance issues caused by
          unnecessary stats for copied revisions have been fixed. The
          full list of changes can be found in the
          ChangeLog. As usual, the source package is
          is available as a tarball compressed using either gzip or bzip2 as
          well as in zip format.

Older news items can be found in the news archive.

Content

Downloads:

rsvndump-0.6.1.tar.gz - Source code distribution

rsvndump-0.6.1.tar.bz2 - Source code distribution

rsvndump-0.6.1.zip - Source code distribution

Previous releases can be found on rsvndump's file list at SourceForge.

Distribution packages/ports:

NOTE: These are not maintained by myself. Thanks go out to the respective packagers!

ArchLinux (AUR)

Fedora

FreeBSD

Gentoo

openSUSE

... and others

Documentation:

README - Requirements and general information

README.win32 - Build instructions for Windows

man page - Online version of the man page

ChangeLog - The rsvndump change log

COPYING - The GPL v3, under which rsvndump is released

Hosted:

The Git repository with issue tracker at GitHub

The project page at SourceForge

The project page at Freshmeat

The project page at Ohloh

Jonas Gehring
          Last update: $DATE


require_dependency 'issue'

module IssuePatch
  def self.included(base) # :nodoc:
    base.extend(ClassMethods)

    base.send(:include, InstanceMethods)

    # Same as typing in the class
    base.class_eval do
      unloadable
    end

  end

  module ClassMethods

  end

  module InstanceMethods
    def helper_spent_hours
      @helper_spent_hours = TimeEntry.sum :hours, :conditions => "user_id != #{assigned_to_id.to_i} AND issue_id = '#{id}'"
    end

    def assigned_spent_hours
      @assigned_spent_hours = TimeEntry.sum :hours, :conditions => "user_id = #{assigned_to_id.to_i} AND issue_id = '#{id}'"
    end

    def self_spent_hours
      @self_spent_hours ||= time_entries.sum(:hours) || 0.00
    end

    def subtask_spent_hours
      time = 0.00
      i.descendants.each do |i|
        time = time + i.time_entries.sum(:hours)
      end
      @subtask_spent_hours = time.to_f
    end

    def estimated_spent
      if estimated_hours == nil or estimated_hours == 0
        @esimtated_spent = "NA"
      else
        @estimated_spent = (assigned_spent_hours/estimated_hours*100).to_i
      end
    end

  end
end

require_dependency 'issue'

module IssuePatch
  def self.included(base) # :nodoc:
    base.extend(ClassMethods)

    base.send(:include, InstanceMethods)

    # Same as typing in the class
    base.class_eval do
      unloadable
    end

  end

  module ClassMethods

  end

  module InstanceMethods
    def helper_spent_hours
      @helper_spent_hours = TimeEntry.sum :hours, :conditions => "user_id != #{assigned_to_id.to_i} AND issue_id = '#{id}'"
    end

    def assigned_spent_hours
      @assigned_spent_hours = TimeEntry.sum :hours, :conditions => "user_id = #{assigned_to_id.to_i} AND issue_id = '#{id}'"
    end

    def self_spent_hours
      @self_spent_hours ||= time_entries.sum(:hours) || 0.00
    end

    def subtask_spent_hours
      time = 0.00
      descendants.each do |i|
        time = time + i.time_entries.sum(:hours)
      end
      @subtask_spent_hours = time.to_f
    end

    def estimated_spent
      if estimated_hours == nil or estimated_hours == 0
        @esimtated_spent = "NA"
      else
        @estimated_spent = (assigned_spent_hours/estimated_hours*100).to_i
      end
    end

  end
end


$:.unshift "#{File.dirname(__FILE__)}/lib"
require 'active_record/acts/list'
ActiveRecord::Base.class_eval { include ActiveRecord::Acts::List }

$:.unshift "#{File.dirname(__FILE__)}/lib"
require 'bundler/setup'
require 'active_record'
require 'active_record/acts/list'
ActiveRecord::Base.class_eval { include ActiveRecord::Acts::List }


<?php

/**
 * abstract class to test sessions instances
 *
 * @author Nicolas Embriz <nbari@dalmp.com>
 * @package DALMP
 * @license BSD License
 * @version 3.0
 */
abstract class test_sessions_base extends PHPUnit_Framework_TestCase {

  abstract public function testAttributes();

  public function getSessionData() {
    return "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";
  }

  public function testOpen() {
    $this->assertTrue($this->sess->open(True, True));
  }

  /**
   * @depends testOpen
   */
  public function testWrite() {
    for ($i = 0; $i < 100; $i++) {
      $this->assertTrue($this->sess->write(sha1("sid_{$i}"), $this->getSessionData()));
    }
  }

  /**
   * @depends testWrite
   */
  public function testRead() {
    for ($i = 0; $i < 100; $i++) {
      $this->assertEquals($this->getSessionData(), $this->sess->read(sha1("sid_{$i}")));
    }
  }

  /**
   * @depends testWrite
   */
  public function testDestroy() {
    for ($i = 0; $i < 100; $i++) {
      $this->assertTrue($this->sess->destroy(sha1("sid_{$i}")));
    }
  }

  /**
   * @depends testOpen
   */
  public function testClose() {
    $this->assertTrue($this->sess->close());
  }

  /**
   * @depends testClose
   */
  public function testGC() {
    $this->assertTrue($this->sess->gc(True));
  }

  public function testWriteRef() {
    for ($i = 0; $i < 100; $i++) {
      $GLOBALS['UID'] = sha1($i);
      $this->assertTrue($this->sess->write(sha1("sid_{$i}"), $this->getSessionData()));
    }
  }

  public function testgetSessionsRefs() {
    $this->assertEquals(100, count($this->sess->getSessionsRefs()));
  }

  public function testgetSessionRef() {
    for ($i = 0; $i < 100; $i++) {
      $this->assertEquals(1, count($this->sess->getSessionRef(sha1($i))));
    }
  }

  public function testdelSessionRef() {
    for ($i = 0; $i < 100; $i++) {
      $this->assertTrue($this->sess->delSessionRef(sha1($i)));
      $this->assertEquals(array(), $this->sess->getSessionRef(sha1($i)));
    }
  }

}

<?php

/**
 * abstract class to test sessions instances
 *
 * @author Nicolas Embriz <nbari@dalmp.com>
 * @package DALMP
 * @license BSD License
 * @version 3.0
 */
abstract class test_sessions_base extends PHPUnit_Framework_TestCase {

  abstract public function testAttributes();

  public function getSessionData() {
    return "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";
  }

  public function testOpen() {
    $this->assertTrue($this->sess->open(True, True));
  }

  /**
   * @depends testOpen
   */
  public function testWrite() {
    for ($i = 0; $i < 100; $i++) {
      $this->assertTrue($this->sess->write(sha1("sid_{$i}"), $this->getSessionData()));
    }
  }

  /**
   * @depends testWrite
   */
  public function testRead() {
    for ($i = 0; $i < 100; $i++) {
      $this->assertEquals($this->getSessionData(), $this->sess->read(sha1("sid_{$i}")));
    }
  }

  /**
   * @depends testWrite
   */
  public function testDestroy() {
    for ($i = 0; $i < 100; $i++) {
      $this->assertTrue($this->sess->destroy(sha1("sid_{$i}")));
    }
  }

  /**
   * @depends testOpen
   */
  public function testClose() {
    $this->assertTrue($this->sess->close());
  }

  /**
   * @depends testClose
   */
  public function testGC() {
    $this->assertTrue($this->sess->gc(True));
  }

  public function testWriteRef() {
    for ($i = 0; $i < 100; $i++) {
      $GLOBALS['UID'] = sha1($i);
      $this->assertTrue($this->sess->write(sha1("sid_{$i}"), $this->getSessionData()));
    }
  }

  public function testGetSessionsRefs() {
    $this->assertEquals(100, count($this->sess->getSessionsRefs()));
  }

  public function testGetSessionRef() {
    for ($i = 0; $i < 100; $i++) {
      $this->assertEquals(1, count($this->sess->getSessionRef(sha1($i))));
    }
  }

  public function testDelSessionRef() {
    for ($i = 0; $i < 100; $i++) {
      $this->assertTrue($this->sess->delSessionRef(sha1($i)));
      $this->assertEquals(array(), $this->sess->getSessionRef(sha1($i)));
    }
  }

}