Skip to content

Instantly share code, notes, and snippets.

View russorat's full-sized avatar
👋

Russ Savage russorat

👋
View GitHub Profile
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#import <unistd.h>
BOOL copy_to_clipboard(NSString *path)
{
// http://stackoverflow.com/questions/2681630/how-to-read-png-image-to-nsimage
NSImage * image;
if([path isEqualToString:@"-"])
{
// http://caiustheory.com/read-standard-input-using-objective-c
@russorat
russorat / pause_and_enable_urls.js
Last active August 29, 2015 14:27
Example of http://www.freeadwordsscripts.com/2014/04/monitor-broken-links-using-mcc-level.html that will pause and enable keywords and ads. Might be very slow.
/******************************************
* Monitor Broken Links Using MCC Level Scripts
* Version 1.5-alt
* Changelog v1.5-alt
* - Added ability to pause and enable keywords/ads
* Changelog v1.4
* - Fixed INVALID_QUERY error
* Changelog v1.3
* - Added previous version of report api to script until
* I update my urls.
@russorat
russorat / google_sheet_to_es_cluster.js
Last active September 1, 2015 19:59
This code is meant to be used on script.google.com in conjuction with a google spreadsheet. It will transform a set of rows and columns (with headers) into json documents and index them in an Elasticsearch cluster.
// If you are running this from a spreadsheet, you can leave this blank and
// it will pick up the active spreadsheet. If you are running this from a
// new script.google.com project, you should put the url of the google sheet here.
var SPREADSHEET_URL = '';
var ES_HOST = {
host : '', // for found.io, something.loc.aws.found.io
port : 9243, // the port, usually 9200 or 9243
username : '',
password : '',
use_ssl : true // set to false to use http
function main() {
var config_options = {
'default' : {
metric : 'Conversions', // This metric will be used for determining duds
threshold : 0, // Duds are less than or equal to this threshold
days_ago : 90, // The timeframe of the data to consider, days ago to yesterday
days_in_limbo : 5 // The script will warn you for this many days before deleting something
}
// If you want, you can add account specific configurations too. If an account specific config
// is not found, the default one from above is used.
/***********
* Find all the keywords that were active daysAgo
* Return those Ids in a mapping so we can easily filter other
* queries.
***********/
function getKeywordsActiveDaysAgo(daysAgo) {
// This will be a mapping of Ids we will return
var keyword_ids = {};
// We are only concerned with the Ids, so let's
// make this as small as possible.
/***********
* Find all the keywords that match a set of criteria. Those keywords
* will be filtered by the set of eligible keywords.
* It returns a list of AdGroup and Keyword Ids to use in a Selector.
***********/
function getDuds(options,eligible_keywords) {
var columns = ['CampaignId',
'AdGroupId',
'Id'];
// Let's add the metric we're using to find the duds
/***********
* Given a set of Ids, an object to store updates in, and the
* max number of days a keyword can be in limbo, this function
* iterates through your account and gathers the changes to be
* made. It also contains the logic to ignore keywords with the
* label "Save" on them. All changes are stored in the arrays within
* the object changes_to_make.
**********/
function findChangesToMake(duds,changes_to_make,max_days_in_limbo) {
// This is the label applied to "Save" a keyword
/***********
* This function applies a set of changes provided.
* It utilizes tight loops to take advantage of any
* batch processing behind the scenes.
***********/
function applyChanges(changes_to_make) {
for(var i in changes_to_make.kw_to_delete) {
changes_to_make.kw_to_delete[i].remove();
}
for(var i in changes_to_make.labels_to_delete) {
/***********
* This is the function that will run in each account. We
* can leverage all the functions we wrote earlier to make
* this as short as possible.
***********/
function findKeywordsToDelete(optionalInput) {
// We are sending over a set of configs from the main
// function. Parse that config, check to see if there is
// an override for this account, or use the default.
var all_configs = JSON.parse(optionalInput);
/***********
* This function verifies that the keywords already in limbo
* but are no longer a dud have the labels removed as needed.
**********/
function checkForRedemption(duds,changes_to_make) {
// An array works well for selectors, but
// it will be much easier to do lookups here if
// we transform the duds array into a map.
var dudsMap = {};
for(var i in duds) {