adparlor-facebook 0.5.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.gitlab-ci.yml +5 -0
- data/.rspec +2 -0
- data/.rubocop.yml +28 -0
- data/.ruby-version +1 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +136 -0
- data/Guardfile +13 -0
- data/LICENSE.txt +21 -0
- data/README.md +164 -0
- data/Rakefile +3 -0
- data/adparlor-facebook.gemspec +38 -0
- data/bin/console +18 -0
- data/bin/gitlab_runner_specs.sh +22 -0
- data/bin/setup +7 -0
- data/lib/adparlor/facebook/api.rb +106 -0
- data/lib/adparlor/facebook/config.rb +24 -0
- data/lib/adparlor/facebook/error.rb +13 -0
- data/lib/adparlor/facebook/graph_api/activity.rb +11 -0
- data/lib/adparlor/facebook/graph_api/ad.rb +43 -0
- data/lib/adparlor/facebook/graph_api/ad_account.rb +168 -0
- data/lib/adparlor/facebook/graph_api/ad_creative.rb +22 -0
- data/lib/adparlor/facebook/graph_api/ad_image.rb +87 -0
- data/lib/adparlor/facebook/graph_api/ad_label.rb +12 -0
- data/lib/adparlor/facebook/graph_api/ad_preview.rb +15 -0
- data/lib/adparlor/facebook/graph_api/ad_set.rb +39 -0
- data/lib/adparlor/facebook/graph_api/ad_targeting_search.rb +64 -0
- data/lib/adparlor/facebook/graph_api/ad_targeting_types/ad_education_major.rb +11 -0
- data/lib/adparlor/facebook/graph_api/ad_targeting_types/ad_education_school.rb +11 -0
- data/lib/adparlor/facebook/graph_api/ad_targeting_types/ad_geolocation.rb +19 -0
- data/lib/adparlor/facebook/graph_api/ad_targeting_types/ad_geolocation_meta.rb +16 -0
- data/lib/adparlor/facebook/graph_api/ad_targeting_types/ad_geolocations/ad_city.rb +13 -0
- data/lib/adparlor/facebook/graph_api/ad_targeting_types/ad_geolocations/ad_country.rb +13 -0
- data/lib/adparlor/facebook/graph_api/ad_targeting_types/ad_geolocations/ad_geo_market.rb +13 -0
- data/lib/adparlor/facebook/graph_api/ad_targeting_types/ad_geolocations/ad_region.rb +13 -0
- data/lib/adparlor/facebook/graph_api/ad_targeting_types/ad_geolocations/ad_zip_code.rb +13 -0
- data/lib/adparlor/facebook/graph_api/ad_targeting_types/ad_interest.rb +11 -0
- data/lib/adparlor/facebook/graph_api/ad_targeting_types/ad_interest_suggestion.rb +12 -0
- data/lib/adparlor/facebook/graph_api/ad_targeting_types/ad_interest_validation.rb +18 -0
- data/lib/adparlor/facebook/graph_api/ad_targeting_types/ad_locale.rb +11 -0
- data/lib/adparlor/facebook/graph_api/ad_targeting_types/ad_radius_suggestion.rb +11 -0
- data/lib/adparlor/facebook/graph_api/ad_targeting_types/ad_targeting_category.rb +18 -0
- data/lib/adparlor/facebook/graph_api/ad_targeting_types/ad_work_employer.rb +11 -0
- data/lib/adparlor/facebook/graph_api/ad_targeting_types/ad_work_position.rb +11 -0
- data/lib/adparlor/facebook/graph_api/ad_video.rb +124 -0
- data/lib/adparlor/facebook/graph_api/ads_pixel.rb +22 -0
- data/lib/adparlor/facebook/graph_api/ads_pixel_stat.rb +25 -0
- data/lib/adparlor/facebook/graph_api/advertisable_application.rb +11 -0
- data/lib/adparlor/facebook/graph_api/app_event_type.rb +11 -0
- data/lib/adparlor/facebook/graph_api/application.rb +15 -0
- data/lib/adparlor/facebook/graph_api/batch_object.rb +147 -0
- data/lib/adparlor/facebook/graph_api/broad_targeting_category.rb +11 -0
- data/lib/adparlor/facebook/graph_api/business.rb +18 -0
- data/lib/adparlor/facebook/graph_api/campaign.rb +43 -0
- data/lib/adparlor/facebook/graph_api/collection_proxy.rb +36 -0
- data/lib/adparlor/facebook/graph_api/connection_object.rb +11 -0
- data/lib/adparlor/facebook/graph_api/custom_audience.rb +31 -0
- data/lib/adparlor/facebook/graph_api/custom_audience_tos.rb +11 -0
- data/lib/adparlor/facebook/graph_api/custom_audience_user.rb +85 -0
- data/lib/adparlor/facebook/graph_api/custom_conversion.rb +22 -0
- data/lib/adparlor/facebook/graph_api/delivery_estimate.rb +11 -0
- data/lib/adparlor/facebook/graph_api/fields/activity.rb +12 -0
- data/lib/adparlor/facebook/graph_api/fields/ad.rb +60 -0
- data/lib/adparlor/facebook/graph_api/fields/ad_account.rb +21 -0
- data/lib/adparlor/facebook/graph_api/fields/ad_creative.rb +23 -0
- data/lib/adparlor/facebook/graph_api/fields/ad_image.rb +14 -0
- data/lib/adparlor/facebook/graph_api/fields/ad_label.rb +11 -0
- data/lib/adparlor/facebook/graph_api/fields/ad_preview.rb +11 -0
- data/lib/adparlor/facebook/graph_api/fields/ad_set.rb +100 -0
- data/lib/adparlor/facebook/graph_api/fields/ad_video.rb +22 -0
- data/lib/adparlor/facebook/graph_api/fields/ads_pixel.rb +12 -0
- data/lib/adparlor/facebook/graph_api/fields/ads_pixel_stat.rb +11 -0
- data/lib/adparlor/facebook/graph_api/fields/advertisable_application.rb +17 -0
- data/lib/adparlor/facebook/graph_api/fields/app_event_type.rb +11 -0
- data/lib/adparlor/facebook/graph_api/fields/application.rb +31 -0
- data/lib/adparlor/facebook/graph_api/fields/broad_targeting_category.rb +12 -0
- data/lib/adparlor/facebook/graph_api/fields/business.rb +11 -0
- data/lib/adparlor/facebook/graph_api/fields/campaign.rb +17 -0
- data/lib/adparlor/facebook/graph_api/fields/connection_object.rb +16 -0
- data/lib/adparlor/facebook/graph_api/fields/custom_audience.rb +22 -0
- data/lib/adparlor/facebook/graph_api/fields/custom_audience_tos.rb +11 -0
- data/lib/adparlor/facebook/graph_api/fields/custom_audience_user.rb +14 -0
- data/lib/adparlor/facebook/graph_api/fields/custom_conversion.rb +14 -0
- data/lib/adparlor/facebook/graph_api/fields/delivery_estimate.rb +11 -0
- data/lib/adparlor/facebook/graph_api/fields/field_decorator.rb +51 -0
- data/lib/adparlor/facebook/graph_api/fields/insight.rb +16 -0
- data/lib/adparlor/facebook/graph_api/fields/instagram_account.rb +11 -0
- data/lib/adparlor/facebook/graph_api/fields/leadgen_form.rb +23 -0
- data/lib/adparlor/facebook/graph_api/fields/page.rb +121 -0
- data/lib/adparlor/facebook/graph_api/fields/page_and_place.rb +11 -0
- data/lib/adparlor/facebook/graph_api/fields/partner_category.rb +12 -0
- data/lib/adparlor/facebook/graph_api/fields/picture.rb +17 -0
- data/lib/adparlor/facebook/graph_api/fields/post.rb +17 -0
- data/lib/adparlor/facebook/graph_api/fields/product_audience.rb +12 -0
- data/lib/adparlor/facebook/graph_api/fields/product_catalog.rb +11 -0
- data/lib/adparlor/facebook/graph_api/fields/product_feed.rb +12 -0
- data/lib/adparlor/facebook/graph_api/fields/product_group.rb +11 -0
- data/lib/adparlor/facebook/graph_api/fields/product_item.rb +18 -0
- data/lib/adparlor/facebook/graph_api/fields/product_set.rb +13 -0
- data/lib/adparlor/facebook/graph_api/fields/reach_estimate.rb +11 -0
- data/lib/adparlor/facebook/graph_api/fields/reach_frequency_prediction.rb +24 -0
- data/lib/adparlor/facebook/graph_api/fields/targeting_sentence_line.rb +11 -0
- data/lib/adparlor/facebook/graph_api/fields/targeting_suggestion.rb +11 -0
- data/lib/adparlor/facebook/graph_api/fields/targeting_validation.rb +11 -0
- data/lib/adparlor/facebook/graph_api/fields/user_lead_gen_info.rb +18 -0
- data/lib/adparlor/facebook/graph_api/fields/video_thumbnail.rb +11 -0
- data/lib/adparlor/facebook/graph_api/graph_object.rb +140 -0
- data/lib/adparlor/facebook/graph_api/insight.rb +18 -0
- data/lib/adparlor/facebook/graph_api/instagram_account.rb +12 -0
- data/lib/adparlor/facebook/graph_api/leadgen_form.rb +10 -0
- data/lib/adparlor/facebook/graph_api/page.rb +27 -0
- data/lib/adparlor/facebook/graph_api/page_and_place.rb +11 -0
- data/lib/adparlor/facebook/graph_api/partner_category.rb +11 -0
- data/lib/adparlor/facebook/graph_api/picture.rb +15 -0
- data/lib/adparlor/facebook/graph_api/post.rb +17 -0
- data/lib/adparlor/facebook/graph_api/product_audience.rb +17 -0
- data/lib/adparlor/facebook/graph_api/product_catalog.rb +27 -0
- data/lib/adparlor/facebook/graph_api/product_feed.rb +11 -0
- data/lib/adparlor/facebook/graph_api/product_group.rb +11 -0
- data/lib/adparlor/facebook/graph_api/product_item.rb +11 -0
- data/lib/adparlor/facebook/graph_api/product_set.rb +26 -0
- data/lib/adparlor/facebook/graph_api/reach_estimate.rb +17 -0
- data/lib/adparlor/facebook/graph_api/reach_frequency_prediction.rb +18 -0
- data/lib/adparlor/facebook/graph_api/targeting_sentence_line.rb +11 -0
- data/lib/adparlor/facebook/graph_api/targeting_suggestion.rb +16 -0
- data/lib/adparlor/facebook/graph_api/targeting_validation.rb +16 -0
- data/lib/adparlor/facebook/graph_api/traits/methods.rb +64 -0
- data/lib/adparlor/facebook/graph_api/user_lead_gen_info.rb +11 -0
- data/lib/adparlor/facebook/graph_api/video_thumbnail.rb +11 -0
- data/lib/adparlor/facebook/graph_api.rb +9 -0
- data/lib/adparlor/facebook/version.rb +5 -0
- data/lib/adparlor/facebook.rb +9 -0
- data/solano.yml +15 -0
- metadata +391 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
module Adparlor
|
2
|
+
module Facebook
|
3
|
+
module GraphApi
|
4
|
+
class Ad < GraphObject
|
5
|
+
include Fields::Ad
|
6
|
+
include Traits::Methods
|
7
|
+
field_attrs FIELDS
|
8
|
+
allow_method :create
|
9
|
+
allow_local_method :create, :update, :destroy
|
10
|
+
|
11
|
+
def path
|
12
|
+
raise FbError.new('required parameter account_id missing', 500) unless account_id
|
13
|
+
"/act_#{account_id}/ads"
|
14
|
+
end
|
15
|
+
|
16
|
+
def update_path
|
17
|
+
raise FbError.new('required parameter id missing', 500) unless id
|
18
|
+
"/#{id}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def adcreatives
|
22
|
+
@adcreatives ||= CollectionProxy.new AdCreative, "/#{id}/adcreatives", access_token
|
23
|
+
end
|
24
|
+
|
25
|
+
def leads
|
26
|
+
@leads ||= CollectionProxy.new UserLeadGenInfo, "/#{id}/leads", access_token
|
27
|
+
end
|
28
|
+
|
29
|
+
def previews
|
30
|
+
@previews ||= CollectionProxy.new(AdPreview, "/#{id}/previews", access_token)
|
31
|
+
end
|
32
|
+
|
33
|
+
def reachestimate
|
34
|
+
@reachestimate ||= CollectionProxy.new ReachEstimate, "/#{id}/reachestimate", access_token
|
35
|
+
end
|
36
|
+
|
37
|
+
def targetingsentencelines
|
38
|
+
@targetingsentencelines ||= CollectionProxy.new TargetingSentenceLine, "/#{id}/targetingsentencelines", access_token
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
module Adparlor
|
2
|
+
module Facebook
|
3
|
+
module GraphApi
|
4
|
+
class AdAccount < GraphObject
|
5
|
+
include Fields::AdAccount
|
6
|
+
include Traits::Methods
|
7
|
+
field_attrs FIELDS
|
8
|
+
allow_method :create, :destroy, :update
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def get(path_or_account_id, options = {})
|
12
|
+
path = path_or_account_id
|
13
|
+
|
14
|
+
begin
|
15
|
+
account_id = Integer(path_or_account_id)
|
16
|
+
path = "/#{normalize_account_id(account_id)}"
|
17
|
+
rescue
|
18
|
+
STDERR.puts 'Invalid account id passed to get'
|
19
|
+
end
|
20
|
+
|
21
|
+
super(path, options)
|
22
|
+
end
|
23
|
+
|
24
|
+
def normalize_account_id(account_id)
|
25
|
+
account_id = account_id.to_s.downcase
|
26
|
+
if account_id.include?('act_')
|
27
|
+
account_id = account_id
|
28
|
+
else
|
29
|
+
account_id = "act_#{account_id}"
|
30
|
+
end
|
31
|
+
account_id
|
32
|
+
end
|
33
|
+
|
34
|
+
def parse_data_for_collection(response)
|
35
|
+
response['data'].first.last
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def normalized_account_id(account_id)
|
40
|
+
"act_#{account_id}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def activities
|
44
|
+
@activities ||= CollectionProxy.new Activity, endpoint('activities'), access_token
|
45
|
+
end
|
46
|
+
|
47
|
+
def adcreatives
|
48
|
+
@adcreatives ||= CollectionProxy.new AdCreative, endpoint('adcreatives'), access_token
|
49
|
+
end
|
50
|
+
|
51
|
+
def adimages
|
52
|
+
@adimages ||= CollectionProxy.new AdImage, endpoint('adimages'), access_token
|
53
|
+
end
|
54
|
+
|
55
|
+
def adlabels
|
56
|
+
@adlabels ||= CollectionProxy.new AdLabel, endpoint('adlabels'), access_token
|
57
|
+
end
|
58
|
+
|
59
|
+
def ads
|
60
|
+
@ads ||= CollectionProxy.new Ad, endpoint('ads'), access_token
|
61
|
+
end
|
62
|
+
|
63
|
+
def adsets
|
64
|
+
@adsets ||= CollectionProxy.new AdSet, endpoint('adsets'), access_token
|
65
|
+
end
|
66
|
+
|
67
|
+
def adspixels
|
68
|
+
@adspixels ||= CollectionProxy.new AdsPixel, endpoint('adspixels'), access_token
|
69
|
+
end
|
70
|
+
|
71
|
+
def advertisable_applications
|
72
|
+
@advertisable_applications ||= CollectionProxy.new AdvertisableApplication, endpoint('advertisable_applications'), access_token
|
73
|
+
end
|
74
|
+
|
75
|
+
def advideos
|
76
|
+
@advideos ||= CollectionProxy.new AdVideo, endpoint('advideos'), access_token
|
77
|
+
end
|
78
|
+
|
79
|
+
def applications
|
80
|
+
@applications ||= CollectionProxy.new Application, endpoint('applications'), access_token
|
81
|
+
end
|
82
|
+
|
83
|
+
def broadtargetingcategories
|
84
|
+
@broadtargetingcategories ||= CollectionProxy.new BroadTargetingCategory, endpoint('broadtargetingcategories'), access_token
|
85
|
+
end
|
86
|
+
|
87
|
+
# Deprecated in v2.6. Please Use advertisable_applications, pages, places endpoint instead
|
88
|
+
def connectionobjects
|
89
|
+
Kernel::fail("connectionobjects is deprecated in v2.6. Use advertisable_applications, pages, places endpoint instead")
|
90
|
+
end
|
91
|
+
|
92
|
+
def campaigns
|
93
|
+
@campaigns ||= CollectionProxy.new Campaign, endpoint('campaigns'), access_token
|
94
|
+
end
|
95
|
+
|
96
|
+
def customaudiences
|
97
|
+
@customaudiences ||= CollectionProxy.new CustomAudience, endpoint('customaudiences'), access_token
|
98
|
+
end
|
99
|
+
|
100
|
+
def customaudiencestos
|
101
|
+
@customaudiencestos ||= CollectionProxy.new CustomAudienceTos, endpoint('customaudiencestos'), access_token
|
102
|
+
end
|
103
|
+
|
104
|
+
def customconversions
|
105
|
+
@customconversions ||= CollectionProxy.new CustomConversion, endpoint('customconversions'), access_token
|
106
|
+
end
|
107
|
+
|
108
|
+
def delivery_estimate
|
109
|
+
@delivery_estimate ||= CollectionProxy.new DeliveryEstimate, endpoint('delivery_estimate'), access_token
|
110
|
+
end
|
111
|
+
|
112
|
+
def generatepreviews
|
113
|
+
@generatepreviews ||= CollectionProxy.new AdPreview, endpoint('generatepreviews'), access_token
|
114
|
+
end
|
115
|
+
|
116
|
+
def insights
|
117
|
+
@insights ||= CollectionProxy.new Insight, endpoint('insights'), access_token
|
118
|
+
end
|
119
|
+
|
120
|
+
def instagram_accounts
|
121
|
+
@instagram_accounts ||= CollectionProxy.new InstagramAccount, endpoint('instagram_accounts'), access_token
|
122
|
+
end
|
123
|
+
|
124
|
+
def offsitepixels
|
125
|
+
Kernel::fail("offsite_pixels is deprecated in v2.7 and above.")
|
126
|
+
end
|
127
|
+
|
128
|
+
def pages
|
129
|
+
@pages ||= CollectionProxy.new PageAndPlace, 'me/accounts', access_token
|
130
|
+
end
|
131
|
+
|
132
|
+
def places
|
133
|
+
@places ||= CollectionProxy.new PageAndPlace, 'me/accounts', access_token, nil, is_place: true
|
134
|
+
end
|
135
|
+
|
136
|
+
def partnercategories
|
137
|
+
@partnercategories ||= CollectionProxy.new PartnerCategory, endpoint('partnercategories'), access_token
|
138
|
+
end
|
139
|
+
|
140
|
+
def reachestimate
|
141
|
+
@reachestimate ||= CollectionProxy.new ReachEstimate, endpoint('reachestimate'), access_token
|
142
|
+
end
|
143
|
+
|
144
|
+
def reachfrequencypredictions
|
145
|
+
@reachfrequencypredictions ||= CollectionProxy.new ReachFrequencyPrediction, endpoint('reachfrequencypredictions'), access_token
|
146
|
+
end
|
147
|
+
|
148
|
+
def targetingsentencelines
|
149
|
+
@targetingsentencelines ||= CollectionProxy.new TargetingSentenceLine, endpoint('targetingsentencelines'), access_token
|
150
|
+
end
|
151
|
+
|
152
|
+
def targetingsuggestions
|
153
|
+
@targetingsuggestions ||= CollectionProxy.new TargetingSuggestion, endpoint('targetingsuggestions'), access_token
|
154
|
+
end
|
155
|
+
|
156
|
+
def targetingvalidation
|
157
|
+
@targetingvalidation ||= CollectionProxy.new TargetingValidation, endpoint('targetingvalidation'), access_token
|
158
|
+
end
|
159
|
+
|
160
|
+
private
|
161
|
+
|
162
|
+
def endpoint(connection)
|
163
|
+
"/#{normalized_account_id(account_id)}/#{connection}"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Adparlor
|
2
|
+
module Facebook
|
3
|
+
module GraphApi
|
4
|
+
class AdCreative < GraphObject
|
5
|
+
include Fields::AdCreative
|
6
|
+
include Traits::Methods
|
7
|
+
field_attrs FIELDS
|
8
|
+
allow_method :create
|
9
|
+
allow_local_method :update, :destroy
|
10
|
+
|
11
|
+
def update_path
|
12
|
+
raise FbError.new('required parameter id missing', 500) unless id
|
13
|
+
"/#{id}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def previews
|
17
|
+
@previews ||= CollectionProxy.new(AdPreview, "/#{id}/previews", access_token)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'mime/types'
|
2
|
+
require 'open-uri'
|
3
|
+
|
4
|
+
module Adparlor
|
5
|
+
module Facebook
|
6
|
+
module GraphApi
|
7
|
+
class AdImage < GraphObject
|
8
|
+
include Fields::AdImage
|
9
|
+
include Traits::Methods
|
10
|
+
field_attrs FIELDS
|
11
|
+
allow_method :create, :destroy
|
12
|
+
allow_local_method :create, :destroy
|
13
|
+
|
14
|
+
def formatted_image
|
15
|
+
return unless @source
|
16
|
+
if %r{https?}.match(@source)
|
17
|
+
file = open(@source)
|
18
|
+
|
19
|
+
# return nil if we can't open the file from the url
|
20
|
+
return nil if file.nil?
|
21
|
+
|
22
|
+
content_type = AdImage.get_content_type(file.content_type, normalized_file_name)
|
23
|
+
extension = AdImage.get_preferred_extension(content_type)
|
24
|
+
|
25
|
+
# if content type or extension doesn't exist, the upload will fail on FB side
|
26
|
+
return nil if content_type.nil? || extension.nil?
|
27
|
+
|
28
|
+
@source = AdImage.upload_file_with_content_type(normalized_file_name, file, content_type, extension)
|
29
|
+
else
|
30
|
+
@source = Faraday::UploadIO.new(normalized_file_name, MIME::Types.type_for(normalized_file_name).first.content_type)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def path
|
35
|
+
raise FbError.new('required parameter account_id missing', 500) unless account_id
|
36
|
+
if account_id.to_s.include?('act_')
|
37
|
+
"/#{account_id}/adimages"
|
38
|
+
else
|
39
|
+
"/act_#{account_id}/adimages"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def post(path, options, method = nil)
|
44
|
+
raise FbError.new('update not available', 500) if method == 'UPDATE'
|
45
|
+
formatted_image
|
46
|
+
super path, options
|
47
|
+
end
|
48
|
+
|
49
|
+
def update_path
|
50
|
+
path
|
51
|
+
end
|
52
|
+
|
53
|
+
class << self
|
54
|
+
def upload_file_with_content_type(normalized_file_name, file, content_type, extension)
|
55
|
+
tmp_file = Tempfile.new([File.basename(normalized_file_name), ".#{extension}"])
|
56
|
+
|
57
|
+
tmp_file.binmode
|
58
|
+
tmp_file.write(file.read)
|
59
|
+
tmp_file.rewind
|
60
|
+
|
61
|
+
Faraday::UploadIO.new(tmp_file.path, content_type)
|
62
|
+
end
|
63
|
+
|
64
|
+
def get_preferred_extension(content_type)
|
65
|
+
MIME::Types[content_type].first.preferred_extension
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_content_type(header_content_type, file_name)
|
69
|
+
content_type = MIME::Types.type_for(file_name)
|
70
|
+
|
71
|
+
return content_type.first.content_type if !file_name.include?('safe_image.php') && !content_type.nil?
|
72
|
+
|
73
|
+
header_content_type.empty? ? nil : header_content_type
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
# Remove any query string parameters before getting the mime type
|
80
|
+
# should probably be done in mime types gem
|
81
|
+
def normalized_file_name
|
82
|
+
@source.split('?').first
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Adparlor
|
2
|
+
module Facebook
|
3
|
+
module GraphApi
|
4
|
+
class AdSet < GraphObject
|
5
|
+
include Fields::AdSet
|
6
|
+
include Traits::Methods
|
7
|
+
field_attrs FIELDS
|
8
|
+
allow_method :create
|
9
|
+
allow_local_method :create, :update, :destroy
|
10
|
+
|
11
|
+
def path
|
12
|
+
raise FbError.new('required parameter account_id missing', 500) unless account_id
|
13
|
+
"/act_#{account_id}/adsets"
|
14
|
+
end
|
15
|
+
|
16
|
+
def update_path
|
17
|
+
raise FbError.new('required parameter id missing', 500) unless id
|
18
|
+
"/#{id}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def activities
|
22
|
+
@activities ||= CollectionProxy.new Activity, "/#{id}/activities", access_token
|
23
|
+
end
|
24
|
+
|
25
|
+
def adcreatives
|
26
|
+
@adcreatives ||= CollectionProxy.new AdCreative, "/#{id}/adcreatives", access_token
|
27
|
+
end
|
28
|
+
|
29
|
+
def ads
|
30
|
+
@ads ||= CollectionProxy.new Ad, "/#{id}/ads", access_token
|
31
|
+
end
|
32
|
+
|
33
|
+
def targetingsentencelines
|
34
|
+
@targetingsentencelines ||= CollectionProxy.new TargetingSentenceLine, "/#{id}/targetingsentencelines", access_token
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Adparlor
|
2
|
+
module Facebook
|
3
|
+
module GraphApi
|
4
|
+
class AdTargetingSearch
|
5
|
+
include Adparlor::Facebook::Api
|
6
|
+
|
7
|
+
def initialize(access_token)
|
8
|
+
@access_token = access_token
|
9
|
+
end
|
10
|
+
|
11
|
+
def path
|
12
|
+
'/search'
|
13
|
+
end
|
14
|
+
|
15
|
+
def search(query, type, options = {})
|
16
|
+
type_param = type.respond_to?(:type_param) ? type.type_param : type.name.split('::').last.downcase
|
17
|
+
params = { q: query, type: type_param, access_token: @access_token }
|
18
|
+
params.merge!(type::OPTIONS) if type.const_defined?('OPTIONS')
|
19
|
+
params.merge!(options)
|
20
|
+
response = get(path, params)
|
21
|
+
if response.body['data'].is_a?(Hash)
|
22
|
+
obj = type.new
|
23
|
+
keys = response.body['data'].keys
|
24
|
+
keys.each do |key|
|
25
|
+
vals = []
|
26
|
+
response.body['data'][key].each do |val|
|
27
|
+
vals << parse_value(key, val.last)
|
28
|
+
end
|
29
|
+
obj.send("#{key}=".to_sym, vals)
|
30
|
+
end
|
31
|
+
obj
|
32
|
+
else
|
33
|
+
response.body['data'].map do |data|
|
34
|
+
obj = type.new
|
35
|
+
data.each do |k, v|
|
36
|
+
obj.send("#{k}=".to_sym, v)
|
37
|
+
end
|
38
|
+
obj
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def parse_value(key, value)
|
46
|
+
case key
|
47
|
+
when 'countries'
|
48
|
+
obj = AdTargetingTypes::AdGeolocations::AdCountry.new
|
49
|
+
when 'cities'
|
50
|
+
obj = AdTargetingTypes::AdGeolocations::AdCity.new
|
51
|
+
when 'regions'
|
52
|
+
obj = AdTargetingTypes::AdGeolocations::AdRegion.new
|
53
|
+
when 'zips'
|
54
|
+
obj = AdTargetingTypes::AdGeolocations::AdZipCode.new
|
55
|
+
else
|
56
|
+
return value.to_s
|
57
|
+
end
|
58
|
+
value.each { |k, v| obj.send("#{k}=".to_sym, v) }
|
59
|
+
obj
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Adparlor
|
2
|
+
module Facebook
|
3
|
+
module GraphApi
|
4
|
+
module AdTargetingTypes
|
5
|
+
class AdGeolocation
|
6
|
+
attr_accessor :key, :name, :type, :supports_city, :supports_region,
|
7
|
+
:country_code, :country_name, :region, :region_id,
|
8
|
+
:primary_city, :primary_city_id, :geo_hierarchy_level, :geo_hierarchy_name
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def type_param
|
12
|
+
'adgeolocation'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Adparlor
|
2
|
+
module Facebook
|
3
|
+
module GraphApi
|
4
|
+
module AdTargetingTypes
|
5
|
+
class AdGeolocationMeta
|
6
|
+
attr_accessor :electoral_districts, :cities, :countries, :custom_locations,
|
7
|
+
:geo_markets, :places, :regions, :zips, :country_groups,
|
8
|
+
:subneighborhoods, :neighborhoods, :subcities, :metro_areas,
|
9
|
+
:large_geo_areas, :small_geo_areas, :medium_geo_areas,
|
10
|
+
:location_cluster_ids
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Adparlor
|
2
|
+
module Facebook
|
3
|
+
module GraphApi
|
4
|
+
module AdTargetingTypes
|
5
|
+
class AdInterestSuggestion
|
6
|
+
attr_accessor :id, :audience_size, :country, :country_access,
|
7
|
+
:description, :name, :partner, :path, :source, :type, :topic
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Adparlor
|
2
|
+
module Facebook
|
3
|
+
module GraphApi
|
4
|
+
module AdTargetingTypes
|
5
|
+
class AdInterestValidation
|
6
|
+
attr_accessor :id, :audience_size, :country, :country_access, :description,
|
7
|
+
:name, :path, :partner, :source, :topic, :type, :valid
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def type_param
|
11
|
+
'adinterestvalid'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Adparlor
|
2
|
+
module Facebook
|
3
|
+
module GraphApi
|
4
|
+
module AdTargetingTypes
|
5
|
+
class AdTargetingCategory
|
6
|
+
attr_accessor :id, :audience_size, :country, :country_access, :description, :name,
|
7
|
+
:real_time_cluster, :partner, :path, :source, :type
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def type_param
|
11
|
+
'adTargetingCategory'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|