Esempio n. 1
0
def create_set(set, display_url, default_bid, default_url, headline, adline1, adline2, keywords, account_email=None):
    '''
    Creates a new keywords set.
    
    The current strategy is to prefer filling up existing campaigns/accounts
    instead of creating new ones. 'keywords' should be a list of strings and/or
    Keyword instances.
    
    Optional account argument can be used to explictly specify which account
    should be used to store a new set. OverflowError will be raised in case
    there's not enough capacity there to store a new set.
    
    @param set: str
    @param display_url: str
    @param default_bid: decimal.Decimal
    @param default_url: str
    @param headline: str
    @param adline1: str
    @param adline2: str
    @param keywords: list
    @param account_email: Account
    
    @return: Account
    '''
    
    if session.query(AdGroup).filter(AdGroup.set == set).count() > 0:
        raise ValueError('Set "%s" already exists' % set)

    if account_email:
        account = session.query(Account).filter(Account.email == account_email).first()
        if not account:
            raise ValueError('Account "%s" not found' % account_email)
    
    processor = None
    
    # getting how many parts should be created
    parts_count = int(len(keywords)) / int(settings.MAX_KEYWORDS_PER_ADGROUP)
    if int(len(keywords)) % int(settings.MAX_KEYWORDS_PER_ADGROUP) != 0:
        parts_count += 1
    if account_email and (parts_count > get_account_capacity(account_email)[0]):
        raise OverflowError('Specified account is not capable enough to store a set')
    
    # looking for campaigns capable to store required number of parts
    campaigns = session.query(Campaign).outerjoin(AdGroup) \
        .group_by(Campaign) \
        .having(func.count('*') <= (settings.MAX_ADGROUPS_PER_CAMPAIGN - parts_count)) \
        .order_by(desc(func.count('*')))
    if account_email:
        campaigns = campaigns.having(Campaign.account_id == account.id)
    
    if campaigns.count() > 0:
        # campaign found
        campaign = campaigns.first()
    else:
        # creating a new campaign
        # looking for an account to use
        if not account_email:
            accounts = session.query(Account).outerjoin(Campaign) \
                .group_by(Account) \
                .having(func.count('*') < settings.MAX_CAMPAIGNS_PER_ACCOUNT) \
                .order_by(desc(func.count('*')))
                
            if accounts.count() > 0:
                account = accounts.first()
            else:
                raise OverflowError('limits exceeded during new set creation')
        
        processor = RequestProcessor(account.email, account.password)
        processor.sign_in()
        
        keywords_part = keywords[:settings.MAX_KEYWORDS_PER_ADGROUP]
        
        new_campaign_name = Campaign.find_unique_name(account)
        new_adgroup_name = AdGroup.find_unique_name(set)
        new_campaign_id, new_adgroup_id = processor.add_campaign(
            new_campaign_name, new_adgroup_name, display_url, preprocess_url(default_url, new_campaign_name, new_adgroup_name), headline, adline1, adline2, 
            preprocess_keywords(keywords_part, plain=True), default_bid
        )
        UsedNames.add_entity(Campaign.__name__, new_campaign_id, account.id, new_campaign_name)
        UsedNames.add_entity(AdGroup.__name__, new_adgroup_id, new_campaign_id, new_adgroup_name)
        processor.set_keywords(new_campaign_id, new_adgroup_id, preprocess_keywords(keywords_part, new_campaign_name, new_adgroup_name))
        
        campaign = Campaign(long(new_campaign_id), account.id)
        session.add(campaign)
        
        adgroup = AdGroup(long(new_adgroup_id), long(new_campaign_id), set,
            default_bid, default_url, display_url, headline, adline1, adline2)
        session.add(adgroup)
        
        keywords = keywords[settings.MAX_KEYWORDS_PER_ADGROUP:]
        
    # now we have a campaign to put the rest of set parts into
    if not processor:
        processor = RequestProcessor(campaign.account.email, campaign.account.password)
        processor.sign_in()

    # creating the rest of set parts
    while len(keywords) > 0:
        keywords_part = keywords[:settings.MAX_KEYWORDS_PER_ADGROUP]
        
        campaign_name = UsedNames.get_entity_name(Campaign.__name__, campaign.id)        
        new_adgroup_name = AdGroup.find_unique_name(set, campaign)
        new_adgroup_id = processor.add_adgroup(
            campaign.id, new_adgroup_name, display_url, preprocess_url(default_url, campaign_name, new_adgroup_name), headline, adline1, adline2, 
            preprocess_keywords(keywords_part, plain=True), default_bid
        )
        UsedNames.add_entity(AdGroup.__name__, new_adgroup_id, campaign.id, new_adgroup_name)
        processor.set_keywords(campaign.id, new_adgroup_id, preprocess_keywords(keywords_part, campaign_name, new_adgroup_name))
        
        adgroup = AdGroup(long(new_adgroup_id), campaign.id, set,
            default_bid, default_url, display_url, headline, adline1, adline2)
        session.add(adgroup)
        
        keywords = keywords[settings.MAX_KEYWORDS_PER_ADGROUP:]

    processor.sign_out()
    session.commit()
    
    return campaign.account
Esempio n. 2
0
def modify_keywords(set, new_keywords):
    '''
    Resubmits the keywords list of a given set with a new one.
    
    List can contain both strings and Keyword instances
    
    @param set: str
    @param keywords: list
    ''' 
    adgroups = session.query(AdGroup).filter(AdGroup.set == set)
    
    if adgroups.count() == 0:
        raise ValueError('Set "%s" not found' % set)
    if len(new_keywords) == 0:
        raise ValueError('"new_keywords" should not be empty')
    
    campaign = adgroups.first().campaign
    processor = RequestProcessor(campaign.account.email, campaign.account.password)
    processor.sign_in()
    
    an_adgroup = adgroups.first()
    adgroups = adgroups.all()
    
    while True:
        adgroup = adgroups.pop(0)
        keywords_part = new_keywords[:settings.MAX_KEYWORDS_PER_ADGROUP]
        new_keywords = new_keywords[settings.MAX_KEYWORDS_PER_ADGROUP:]
        
        campaign_name = UsedNames.get_entity_name(Campaign.__name__, campaign.id)
        adgroup_name = UsedNames.get_entity_name(AdGroup.__name__, adgroup.id)
        processor.set_keywords(campaign.id, adgroup.id, preprocess_keywords(keywords_part, campaign_name, adgroup_name))
        
        if len(adgroups) == 0 or len(new_keywords) == 0:
            break
        
    if len(adgroups) > 0:
        for adgroup_to_remove in adgroups:
            processor.delete_adgroup(campaign.id, adgroup_to_remove.id)
            session.delete(adgroup_to_remove)
            
    while len(new_keywords) > 0:
        if not (len(campaign.adgroups) < settings.MAX_ADGROUPS_PER_CAMPAIGN):
            raise OverflowError('limits exceeded during modifying keywords')
        
        new_adgroup_name = AdGroup.find_unique_name(set, campaign)
        campaign_name = UsedNames.get_entity_name(Campaign.__name__, campaign.id)
        new_adgroup_id = processor.add_adgroup(
            campaign.id, new_adgroup_name, an_adgroup.display_url, preprocess_url(an_adgroup.default_url, campaign_name, new_adgroup_name), 
            an_adgroup.headline, an_adgroup.adline1, an_adgroup.adline2, 
            preprocess_keywords(new_keywords[:settings.MAX_KEYWORDS_PER_ADGROUP], plain=True), an_adgroup.default_bid
        )
        UsedNames.add_entity(AdGroup.__name__, new_adgroup_id, campaign.id, new_adgroup_name)
        processor.set_keywords(campaign.id, new_adgroup_id, preprocess_keywords(new_keywords[:settings.MAX_KEYWORDS_PER_ADGROUP], campaign_name, new_adgroup_name))
        
        adgroup = AdGroup(long(new_adgroup_id), campaign.id, set,
            an_adgroup.default_bid, an_adgroup.default_url, an_adgroup.display_url, 
            an_adgroup.headline, an_adgroup.adline1, an_adgroup.adline2)
        session.add(adgroup)
        
        new_keywords = new_keywords[settings.MAX_KEYWORDS_PER_ADGROUP:]
        
    session.commit()
    processor.sign_out()
Esempio n. 3
0
def clone_account(email_source, email_dest):
    '''
    Clones an account identified by its email to another one.
    
    Destination account should be empty (or at least to be capable enough
    to store all source account data). Removes source account after cloning.
    
    @param email_source: str
    @param email_dest: str
    '''
    account_from = session.query(Account).filter(Account.email == email_source).one()
    account_to = session.query(Account).filter(Account.email == email_dest).one()
    
    processor_from = RequestProcessor(account_from.email, account_from.password)
    processor_from.sign_in()
    
    processor_to = RequestProcessor(account_to.email, account_to.password)
    processor_to.sign_in()
    
    campaigns = session.query(Campaign).join(AdGroup).group_by(Campaign) \
        .filter(Campaign.account_id == account_from.id).all()
        
    for campaign in campaigns:
        adgroups = session.query(AdGroup).filter(AdGroup.campaign_id == campaign.id).all()
        first_adgroup = adgroups.pop(0)
        first_adgroup_keywords = processor_from.get_keywords(campaign.id, first_adgroup.id)
        
        new_campaign_name = Campaign.find_unique_name(account_to)
        new_adgroup_name = AdGroup.find_unique_name(first_adgroup.set)
        new_campaign_id, new_adgroup_id = processor_to.add_campaign(
            new_campaign_name, new_adgroup_name,
            first_adgroup.display_url, preprocess_url(first_adgroup.default_url, new_campaign_name, new_adgroup_name), 
            first_adgroup.headline, first_adgroup.adline1, first_adgroup.adline2, 
            preprocess_keywords(first_adgroup_keywords, plain=True), first_adgroup.default_bid
        )
        UsedNames.add_entity(Campaign.__name__, new_campaign_id, account_to.id, new_campaign_name)
        UsedNames.add_entity(AdGroup.__name__, new_adgroup_id, new_campaign_id, new_adgroup_name)
        
        processor_to.set_keywords(new_campaign_id, new_adgroup_id, preprocess_keywords(first_adgroup_keywords, new_campaign_name, new_adgroup_name))
        
        session.add(Campaign(long(new_campaign_id), account_to.id))
        session.add(AdGroup(long(new_adgroup_id), long(new_campaign_id), first_adgroup.set, 
                first_adgroup.default_bid, first_adgroup.default_url, first_adgroup.display_url, 
                first_adgroup.headline, first_adgroup.adline1, first_adgroup.adline2))
        
        for adgroup in adgroups:
            adgroup_keywords = processor_from.get_keywords(campaign.id, adgroup.id)
            
            campaign_name = UsedNames.get_entity_name(Campaign.__name__, campaign.id)
            new_adgroup_name = AdGroup.find_unique_name(adgroup.set, campaign)
            new_adgroup_id = processor_to.add_adgroup(
                campaign.id, new_adgroup_name, adgroup.display_url, preprocess_url(adgroup.default_url, campaign_name, new_adgroup_name), 
                adgroup.headline, adgroup.adline1, adgroup.adline2, 
                preprocess_keywords(adgroup_keywords, plain=True), adgroup.default_bid
            )
            UsedNames.add_entity(AdGroup.__name__, new_adgroup_id, campaign.id, new_adgroup_name)
            processor_to.set_keywords(campaign.id, adgroup.id, preprocess_keywords(first_adgroup_keywords, campaign_name, new_adgroup_name))
            
            session.add(AdGroup(long(new_adgroup_id), campaign.id, adgroup.set,
                adgroup.default_bid, adgroup.default_url, adgroup.display_url, 
                adgroup.headline, adgroup.adline1, adgroup.adline2))
            
    session.commit()
    processor_from.sign_out()
    processor_to.sign_out()
    remove_account(email_source)