Adwords API report segmenting - google-ads-api

i'm trying to create google adwords report that will gain me
clicks,shows,cost,bounce,goal reach count
for each:
ad id, pharse id, goal id, day
(like group by)
There are a lot of different report types and i can't get how to create that kind of report.
Im using googleads-php-lib, so here is the code from example:
$selector = new Selector();
$selector->fields = array('Id', 'Clicks', 'Cost');
// Optional: use predicate to filter out paused criteria.
//$selector->predicates[] = new Predicate('Status', 'NOT_IN', array('PAUSED'));
// Create report definition.
$reportDefinition = new ReportDefinition();
$reportDefinition->selector = $selector;
$reportDefinition->reportName = 'Criteria performance report #' . uniqid();
$reportDefinition->dateRangeType = 'LAST_90_DAYS';
$reportDefinition->reportType = 'AD_PERFORMANCE_REPORT';
$reportDefinition->downloadFormat = 'CSV';

Sometimes you can't get all data in the same report. You can see all the report types in the AdWords Docs:
https://developers.google.com/adwords/api/docs/appendix/reports

You can add Segment in selector->fields
Example: ClickType is a segment so it will be implemented as given below.
$selector->fields = array('Id', 'Clicks', 'Cost', 'ClickType');
or with CriteriaReportWithAwql
$query = (new ReportQueryBuilder())
->select([
'CampaignId',
'CampaignName',
'Impressions',
'Clicks',
'Cost',
'ClickType',
'AccountCurrencyCode',
])
->from(ReportDefinitionReportType::CRITERIA_PERFORMANCE_REPORT)
->where('Status')->in(['ENABLED', 'PAUSED'])
->where('CampaignId')->in(['90045151'])
->during($startDate, $endDate)
->build();

Related

How to combine a term query with a suggestion using Spring Data Elastic Search

I need to ensure that my suggestions come from documents with a particular join field.
I can create a term query:
QueryBuilder typeFilter = QueryBuilders.termQuery("joinField", "foo");
And I can run a search with suggestbuilder:
SuggestBuilder suggestBuilder = new SuggestBuilder();
suggestBuilder.addSuggestion("fieldname", SuggestBuilders
.phraseSuggestion("fieldname")
.text(searchTerm)
.size(10));
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
sourceBuilder.suggest(suggestBuilder);
SearchRequest searchRequest = new SearchRequest("MyIndex")
searchRequest.source(sourceBuilder);
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
But I can't see how to get suggestions only from documents returned by the termQuery.
NB "client" here is a RestHighLevelClient. I am using spring-data-elastic-search:4.1.5. NativeSearchQueryBuilder.withSuggestBuilder is not available to me because that was introduced in 4.3 and I am not able to upgrade
Looks like collateQuery is what I was looking for:
QueryBuilder typeFilter = QueryBuilders.termQuery("joinField", "foo");
SuggestBuilder suggestBuilder = new SuggestBuilder();
suggestBuilder.addSuggestion("fieldname", SuggestBuilders
.phraseSuggestion("fieldname")
.collateQuery(typeFilter.toString())
.text(searchTerm)
.size(10));

Importing Url's of sheets shared with me into google sheets automatically whenever one is shared

I'm pretty new to excel or google sheets. The work place, that I work at does not have anything stream lined.
I'm trying to create my own work book that I can refresh everyday I log in so that I can have a list of things that I need to work on for that day.
One of the functions that I would like to have is, whenever a new sheet is shared with me on Google Sheets, I want the URL for that sheet to populate in one of the cells in my workbook automatically and arranged based on timestamp.
I was trying to search for this on Google, but I read that: shared with me docs are not stored anywhere specifically.
Any help or pointing me in the right direction is highly appreciated.
It is easy to fetch the files that have been shared with you. For that, you can simply call the Drive API's Files: list method specifying in the q parameter the sharedWithMe attribute.
Afterwards, you can use the SpreadsheetApp class to gather a spreadsheet and insert data into it. In this case, you can simply make several calls of apendRow() to insert the results.
Finally, properties can be used to store the status of the script (last date checked), so that it can know where to resume from. In this case below, we'll be saving the date in the LAST_DATE property.
Code.gs
var SPREADSHEET_ID = 'YOUR_SPREADSHEET_ID';
var SHEET_NAME = 'YOUR_SHEET_NAME';
function myFunction() {
var sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(SHEET_NAME);
var lastDate = new Date(PropertiesService.getScriptProperties().getProperty('LAST_DATE'));
var currentDate = new Date();
var files = getFiles(lastDate);
for (var i=0; i<files.length; i++) {
var row = [
new Date(files[i].sharedWithMeDate),
files[i].title,
files[i].alternateLink,
files[i].sharingUser.emailAddress,
files[i].owners.map(getEmail).join(', ')];
sheet.appendRow(row);
}
console.log('lastDate: %s, currentDate: %s, events added: %d', lastDate, currentDate, files.length);
PropertiesService.getScriptProperties().setProperty('LAST_DATE', currentDate.toISOString());
}
function getEmail(user) {
return user.emailAddress;
}
function getFiles(lastSharedDate) {
var query = "sharedWithMe and mimeType = 'application/vnd.google-apps.spreadsheet'";
var res = Drive.Files.list({
q: query,
orderBy: "sharedWithMeDate desc",
fields: "*",
pageSize: 1000
});
// `query` parameter cannot compare sharedWithMeDate, so we do it afterwards
return res.items.filter(function (i) {
return (new Date(i.sharedWithMeDate) > lastSharedDate);
}).reverse();
}
You can set up the script to be ran periodically (i.e once a day, or more in case you'd need it) using Time-driven triggers.

How to display list_filter with count of related objects in django admin?

How can I display the count of related objects after each filter in list_filter in django admin?
class Application(TimeStampModel):
name = models.CharField(verbose_name='CI Name', max_length=100, unique=True)
description = models.TextField(blank=True, help_text="Business application")
class Server(TimeStampModel):
name = models.CharField(max_length=100, verbose_name='Server Name', unique=True)
company = models.CharField(max_length=3, choices=constants.COMPANIES.items())
online = models.BooleanField(default=True, blank=True, verbose_name='OnLine')
application_members = models.ManyToManyField('Application',through='Rolemembership',
through_fields = ('server', 'application'),
)
class Rolemembership(TimeStampModel):
server = models.ForeignKey(Server, on_delete = models.CASCADE)
application = models.ForeignKey(Application, on_delete = models.CASCADE)
name = models.CharField(verbose_name='Server Role', max_length=50, choices=constants.SERVER_ROLE.items())
roleversion = models.CharField(max_length=100, verbose_name='Version', blank=True)
Admin.py
#admin.register(Server)
class ServerAdmin(admin.ModelAdmin):
save_on_top = True
list_per_page = 30
list_max_show_all = 500
inlines = [ServerInLine]
list_filter = (
'region',
'rolemembership__name',
'online',
'company',
'location',
'updated_on',
)
i.e After each filter in list filter, I want to show the count of related objects.
Now it only shows the list of filter
i.e location filter list
Toronto
NY
Chicago
I want the filter to show the count like below:
Toronto(5)
NY(3)
Chicago(2)
And if the filter has 0 related objects, don't display the filter.
This is possible with a custom list filter by combining two ideas.
One: the lookups method lets you control the value used in the query string and the text displayed as filter text.
Two: you can inspect the data set when you build the list of filters. The docs at https://docs.djangoproject.com/en/1.11/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter shows examples for a start decade list filter (always shows «80s» and «90s») and a dynamic filter (shows «80s» if there are matching records, same for «90s»).
Also as a convenience, the ModelAdmin object is passed to the lookups
method, for example if you want to base the lookups on the available
data
This is a filter I wrote to filter data by language:
class BaseLanguageFilter(admin.SimpleListFilter):
title = _('language')
parameter_name = 'lang'
def lookups(self, request, model_admin):
# Inspect the existing data to return e.g. ('fr', 'français (11)')
# Note: the values and count are computed from the full data set,
# ignoring currently applied filters.
qs = model_admin.get_queryset(request)
for lang, name in settings.LANGUAGES:
count = qs.filter(language=lang).count()
if count:
yield (lang, f'{name} ({count})')
def queryset(self, request, queryset):
# Apply the filter selected, if any
lang = self.value()
if lang:
return queryset.filter(language=lang)
You can start from that and adapt it for your cities by replacing the part with settings.LANGUAGES with a queryset aggregation + values_list that will return the distinct values and counts for cities.
Éric's code got me 80% of what I needed. To address the comment he left in his code (about ignoring currently applied filters), I ended up using the following for my use case:
from django.db.models import Count
class CountAnnotatedFeedFilter(admin.SimpleListFilter):
title = 'feed'
parameter_name = 'feed'
def lookups(self, request, model_admin):
qs = model_admin.get_queryset(request).filter(**request.GET.dict())
for pk, name, count in qs.values_list('feed__feed_id', 'feed__feed_name').annotate(total=Count('feed')).order_by('-total'):
if count:
yield pk, f'{name} ({count})'
def queryset(self, request, queryset):
feed_id = self.value()
if feed_id:
return queryset.filter(feed_id=feed_id)
And then, in the admin model:
class FeedEntryAdmin(admin.ModelAdmin):
list_filter = (CountAnnotatedFeedFilter,)
Note: As Éric also mentioned, this can impact the speed of the admin panel quite heavily, as it may have to perform expensive queries.

Create multiple relationships with py2neo

I want to create multiple relationships between the same node using py2neo library. I used create if the relationship does not exist and merge when it exists. Here is a sample of my code :
def create_route(graph, sourcefile, airport_nodes):
with open(sourcefile, encoding="utf8") as csvfile:
reader = csv.DictReader(csvfile)
fieldnames = reader.fieldnames
for row in reader:
source_airport = row['origin']
destination_airport = row['destination']
source_airport_node = airport_nodes[source_airport]
destination_airport_node = airport_nodes[destination_airport]
node_properties = {'distance':row['distance']}
node_properties1 = {'duration': row['duration']}
graph.create(Relationship(source_airport_node, destination_airport_node,**node_properties1))
graph.merge(Relationship(source_airport_node, destination_airport_node, **node_properties))
The problem that It get only one relationship with the last attribute which is the distance.
Thank you

SOAPpy - create a Jira issue and define a component?

I can't figure how to create a jira issue and define its component with SOAPpy:
client = so.WSDL.Proxy(cfg_wsld)
auth_token = client.login(cfg_username, cfg_password)
issue_params = dict()
issue_params['project'] = project
issue_params['type'] = issue_type
issue_params['summary'] = summary
issue_params['description'] = summary
newissue = client.createIssue(auth_token, issue_params)
This sample works fine but I try to add components to it Jira will return missmatchTypeException.
I've tried all kinds of variants: passing arrays, strings, ints into it but it won't pick any of them up.
Most attempts (passing string, int, array of both) will cause TypeMissmatch, this causes NullPointerException inside Jira:
issue_params['components'] = {u'Разное': {'id': '11143', 'name': u'Разное'}}
I know the exact id of the issue type I want to use but how do I pass it properly? When I retrieve an issue with this type components returns as SOAPpy.Types.typedArrayType() but this still fails:
issue_params['components'] = so.Types.typedArrayType(data={'id': '11143', 'name': u'Разное'})
newissue = client.createIssue(auth_token, issue_params)
(<class 'SOAPpy.Errors.Error'>, <Error : Data must be a sequence>, None)
issue_params['components'] = so.Types.typedArrayType(data=[{'id': '11143', 'name': u'Разное'},])
This did the trick - data needs to be an array.

Resources