playwire 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +74 -0
- data/bin/playwire +84 -0
- data/lib/playwire/android.rb +207 -0
- data/lib/playwire/ios.rb +152 -0
- data/lib/playwire/logger.rb +22 -0
- data/lib/playwire/network.rb +31 -0
- data/lib/playwire/plist.rb +25 -0
- data/lib/playwire/pwc.rb +41 -0
- data/lib/playwire/uri_builder.rb +23 -0
- data/lib/playwire/version.rb +5 -0
- data/lib/playwire.rb +41 -0
- metadata +142 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a7859fcc12cf59c318da09493ca353252fc6833e8d53c79a01c12074f799884c
|
4
|
+
data.tar.gz: 8107c469313d08c9ab27540b009a629bed5cf5474a62db14bc244063092c23cb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 76ff496510a7536f945bbbd6f1482b2a99659b4eaa9b9a12d319aee2639c3b4bf4cccb5bc3410e003ec14bceed116333762237836579eb8d701aab85cc71ea04
|
7
|
+
data.tar.gz: 8e579656a4606adec19c5a8463d9c258348ab152f02a374ad02da0c326121eee9a0d550947ce4c7492fbf469df7d42dbe572ec9ece0ca12e08c035b543f3934d
|
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2023 Playwire
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Playwire CLI 0.1.0
|
2
|
+
|
3
|
+
Playwire CLI helps you to automate onboarding tasks and avoid error-prone situations during Playwire SDK integration. It is built with Ruby and it will be installable with the default Ruby available on macOS.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Follow these steps to install the Playwire CLI to your machine:
|
8
|
+
|
9
|
+
- Install the Playwire gem, run the next command in a terminal window.
|
10
|
+
|
11
|
+
```console
|
12
|
+
$ sudo gem install playwire
|
13
|
+
```
|
14
|
+
|
15
|
+
- Verify installation by running the version command.
|
16
|
+
|
17
|
+
```console
|
18
|
+
$ playwire version
|
19
|
+
```
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Open a terminal window, move to your project directory and run the following commands.
|
24
|
+
|
25
|
+
### iOS
|
26
|
+
|
27
|
+
#### SKAdNetwork items
|
28
|
+
|
29
|
+
The command downloads a set of required SKAdNetwork items, seeks for the project’s Info.plist file and modifies it. By default, this command analyzes your Podfile to detect a target where Playwire SDK dependency is used and which Info.plist should be modified.
|
30
|
+
|
31
|
+
```console
|
32
|
+
$ playwire ios sk_ad_network_items
|
33
|
+
```
|
34
|
+
|
35
|
+
You can optionally specify the _--plist_ option, which will set your custom Info.plist path.
|
36
|
+
|
37
|
+
```console
|
38
|
+
$ playwire ios sk_ad_network_items --plist "path/to/Info.plist"
|
39
|
+
```
|
40
|
+
|
41
|
+
#### GADApplicationIdentifier
|
42
|
+
|
43
|
+
The command downloads the pub’s config file, extracts gamAppId, seeks for the project’s Info.plist file and modifies it. You must provide publisher and app ids to run this command, make sure you have the metadata or contact Playwire Contact Manager to receive these ids.
|
44
|
+
By default, this command analyzes your Podfile to detect a target where Playwire SDK dependency is used and which Info.plist should be modified.
|
45
|
+
|
46
|
+
```console
|
47
|
+
$ playwire ios gam_app_id --pub_id "00000" --app_id "123"
|
48
|
+
```
|
49
|
+
|
50
|
+
You can optionally specify the _--plist_ option, which will set your custom Info.plist path.
|
51
|
+
|
52
|
+
```console
|
53
|
+
$ playwire ios gam_app_id --pub_id "00000" --app_id "123" --plist "path/to/Info.plist"
|
54
|
+
```
|
55
|
+
|
56
|
+
### Android
|
57
|
+
|
58
|
+
#### com.google.android.gms.ads.APPLICATION_ID
|
59
|
+
|
60
|
+
The command downloads the pub’s config file, extracts gamAppId, seeks for the project’s AndroidManifest.xml file and modifies it. You must provide publisher and app ids to run this command, make sure you have the metadata or contact Playwire Contact Manager to receive these ids.
|
61
|
+
|
62
|
+
```console
|
63
|
+
$ playwire android gam_app_id --pub_id "00000" --app_id "123"
|
64
|
+
```
|
65
|
+
|
66
|
+
You can optionally specify the _--manifest_ option, which will set your custom AndroidManifest.xml path.
|
67
|
+
|
68
|
+
```console
|
69
|
+
$ playwire android gam_app_id --pub_id "00000" --app_id "123" --manifest "path/to/AndroidManifest.xml"
|
70
|
+
```
|
71
|
+
|
72
|
+
## License
|
73
|
+
|
74
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/bin/playwire
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'playwire'
|
4
|
+
require 'playwire/version'
|
5
|
+
require 'thor'
|
6
|
+
|
7
|
+
module Playwire
|
8
|
+
class CLI < Thor
|
9
|
+
|
10
|
+
def self.exit_on_failure?
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
class IOS < Thor
|
15
|
+
option :plist, :desc => "The path to the 'Info.plist' file of your poject.", :required => false, :type => :string
|
16
|
+
desc "sk_ad_network_items", "Update the 'Info.plist' file with required SKAdNetwork items. Use --plist option to set custom 'Info.plist' path."
|
17
|
+
long_desc <<-LONGDESC
|
18
|
+
> $ playwire ios sk_ad_network_items
|
19
|
+
The command above will update a detected 'Info.plist' file with required SKAdNetwork items.
|
20
|
+
|
21
|
+
You can optionally specify the --plist option, which will set your custom 'Info.plist' path.
|
22
|
+
> $ playwire ios sk_ad_network_items --plist "path/to/Info.plist"
|
23
|
+
LONGDESC
|
24
|
+
def sk_ad_network_items
|
25
|
+
Playwire::Command::IOS.load_skadnetwork_and_set_to_info_plist(options[:plist])
|
26
|
+
end
|
27
|
+
|
28
|
+
option :pub_id, :banner => "", :required => true, :type => :string
|
29
|
+
option :app_id, :banner => "", :required => true, :type => :string
|
30
|
+
option :plist, :banner => "", :required => false, :type => :string
|
31
|
+
desc "gam_app_id", "Update the 'Info.plist' file with 'gamAppId' from the pub's config file. Use --plist option to set custom 'Info.plist' path."
|
32
|
+
long_desc <<-LONGDESC
|
33
|
+
> $ playwire ios gam_app_id --pub_id "00000" --app_id "123"
|
34
|
+
|
35
|
+
The command above will update a detected 'Info.plist' file with 'GADApplicationIdentifier' from the pub's config file.
|
36
|
+
You can optionally specify the --plist option, which will set your custom 'Info.plist' path.
|
37
|
+
|
38
|
+
> $ playwire ios gam_app_id --pub_id "00000" --app_id "123" --plist "path/to/Info.plist"
|
39
|
+
LONGDESC
|
40
|
+
def gam_app_id
|
41
|
+
Playwire::Command::IOS.load_config_and_set_gam_app_id(
|
42
|
+
options[:pub_id],
|
43
|
+
options[:app_id],
|
44
|
+
options[:plist]
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class Android < Thor
|
50
|
+
option :pub_id, :banner => "", :required => true, :type => :string
|
51
|
+
option :app_id, :banner => "", :required => true, :type => :string
|
52
|
+
option :manifest, :banner => "", :required => false, :type => :string
|
53
|
+
desc "gam_app_id", "Update the 'AndroidManifest.xml' file with 'gamAppId' from the pub's config file. Use --manifest option to set custom 'AndroidManifest.xml' path."
|
54
|
+
long_desc <<-LONGDESC
|
55
|
+
> $ playwire android gam_app_id --pub_id "00000" --app_id "123"
|
56
|
+
|
57
|
+
The command above will update a detected 'AndroidManifest.xml' file with 'com.google.android.gms.ads.APPLICATION_ID' from the pub's config file.
|
58
|
+
You can optionally specify the --manifest option, which will set your custom 'AndroidManifest.xml' path.
|
59
|
+
|
60
|
+
> $ playwire android gam_app_id --pub_id "00000" --app_id "123" --manifest "path/to/AndroidManifest.xml"
|
61
|
+
LONGDESC
|
62
|
+
def gam_app_id
|
63
|
+
Playwire::Command::Android.load_config_and_set_gam_app_id(
|
64
|
+
options[:pub_id],
|
65
|
+
options[:app_id],
|
66
|
+
options[:manifest]
|
67
|
+
)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
desc "version", "Returns the current version of Playwire CLI."
|
72
|
+
def version
|
73
|
+
puts Playwire::VERSION
|
74
|
+
end
|
75
|
+
|
76
|
+
desc "SUBCOMMAND ...ARGS", "Run iOS related commands."
|
77
|
+
subcommand "ios", IOS
|
78
|
+
|
79
|
+
desc "SUBCOMMAND ...ARGS", "Run Android related commands."
|
80
|
+
subcommand "android", Android
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
Playwire::CLI.start(ARGV)
|
@@ -0,0 +1,207 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'nokogiri'
|
5
|
+
|
6
|
+
require_relative 'pwc'
|
7
|
+
require_relative 'network'
|
8
|
+
require_relative 'logger'
|
9
|
+
|
10
|
+
module Playwire
|
11
|
+
class Android
|
12
|
+
|
13
|
+
PWC = Playwire::PWC::AndroidManifest
|
14
|
+
|
15
|
+
def seek_for_gradle_files
|
16
|
+
### Look for 'AndroidManifest.xml' paths
|
17
|
+
return Dir.glob(File.join(Pathname.pwd, '**', '*')).filter { |file| file =~ /.+\/build\.gradle/ }.flatten
|
18
|
+
end
|
19
|
+
|
20
|
+
def is_playwire_sdk_installed(path, sdk)
|
21
|
+
### Look for Playwire SDK dependencies in the build.gradle
|
22
|
+
build_gradle = File.read(path)
|
23
|
+
matches = build_gradle.scan(/['"]#{sdk}:.+['"]/)
|
24
|
+
return !matches.empty?
|
25
|
+
end
|
26
|
+
|
27
|
+
def seek_for_manifests
|
28
|
+
### Look for 'AndroidManifest.xml' paths
|
29
|
+
manifests = Dir.glob(File.join(Pathname.pwd, '**', '*'))
|
30
|
+
.filter { |file| file =~ /.+src.+\/AndroidManifest\.xml/ }.flatten
|
31
|
+
|
32
|
+
### Return error if 'AndroidManifest.xml' files haven't been found
|
33
|
+
if manifests.empty?
|
34
|
+
Playwire::Logger.error("No 'AndroidManifest.xml' found in the project directory. Use --manifest option to define the 'AndroidManifest.xml' path manually.")
|
35
|
+
return nil
|
36
|
+
end
|
37
|
+
return manifests
|
38
|
+
end
|
39
|
+
|
40
|
+
def validate_manifest_path_from_user(manifest_path)
|
41
|
+
### Converts any pathname to an absolute pathname.
|
42
|
+
path = File.expand_path(manifest_path, __FILE__)
|
43
|
+
|
44
|
+
### Verify that file exists and the path doesn't point to directory.
|
45
|
+
isExist = File.exist?(path)
|
46
|
+
isDirectory = File.directory?(path)
|
47
|
+
|
48
|
+
### Return error if the file doesn't meet condition.
|
49
|
+
if !isExist || isDirectory
|
50
|
+
Playwire::Logger.error("No a '.xml' file found at the path provided by '--manifest'. Check if the '.xml' file exists at the path.")
|
51
|
+
return nil
|
52
|
+
end
|
53
|
+
|
54
|
+
return [path]
|
55
|
+
end
|
56
|
+
|
57
|
+
def load_config_and_set_gam_app_id(publisher_id, app_id, user_manifest_path=nil)
|
58
|
+
### Iterate over build.gradle files to check if contains Playwire SDK dependency
|
59
|
+
gradle_files = seek_for_gradle_files()
|
60
|
+
puts gradle_files
|
61
|
+
is_total_dependency = gradle_files.filter { |path| is_playwire_sdk_installed(path, PWC::PWC_TOTAL_DEPENDENCY) }.length > 0
|
62
|
+
puts "Total #{is_total_dependency}"
|
63
|
+
is_coppa_dependency = gradle_files.filter { |path| is_playwire_sdk_installed(path, PWC::PWC_COPPA_DEPENDENCY) }.length > 0
|
64
|
+
puts "COPPA #{is_coppa_dependency}"
|
65
|
+
### Return error if Playwire SDK dependency hasn't been found
|
66
|
+
if !is_total_dependency && !is_coppa_dependency
|
67
|
+
Playwire::Logger.error("No 'Playwire SDK' dependency found in the Podfile.")
|
68
|
+
return
|
69
|
+
end
|
70
|
+
|
71
|
+
### Use 'AndroidManifest.xml' provided by a pub or looking for 'AndroidManifest.xml' paths.
|
72
|
+
manifest_paths = user_manifest_path.nil? ? seek_for_manifests() : validate_manifest_path_from_user(user_manifest_path)
|
73
|
+
return unless manifest_paths
|
74
|
+
|
75
|
+
### Load config file with metadata provided by a pub or return error if the config file does't exist
|
76
|
+
json = Playwire::Network.load_config(publisher_id, app_id)
|
77
|
+
if json.nil?
|
78
|
+
Playwire::Logger.error("No config file found for the publisher. Check the entered metadata or contact Playwire Account Manager to resolve this issue.")
|
79
|
+
return
|
80
|
+
end
|
81
|
+
|
82
|
+
### Extract 'gamAppId' or return error if the 'gamAppId' is omitted
|
83
|
+
gam_app_id = json.dig('settings', 'gamAppId')
|
84
|
+
if gam_app_id.nil?
|
85
|
+
Playwire::Logger.error("No 'gamAppId' found for the publisher. Contact Playwire Account Manager to resolve this issue.")
|
86
|
+
return
|
87
|
+
end
|
88
|
+
|
89
|
+
manifest_paths.each { |path|
|
90
|
+
### Open and modify the 'AndroidManifest.xml' file
|
91
|
+
modify_android_manifest_file(path, gam_app_id, is_total_dependency)
|
92
|
+
}
|
93
|
+
|
94
|
+
Playwire::Logger.success("The 'AndroidManifest.xml' has been updated with 'gamAppId' = #{gam_app_id}.")
|
95
|
+
end
|
96
|
+
|
97
|
+
def modify_android_manifest_file(path, gam_app_id, is_total_dependency)
|
98
|
+
### Open and parse the 'AndroidManifest.xml' file
|
99
|
+
document = parse_manifest_file(path)
|
100
|
+
return unless document
|
101
|
+
|
102
|
+
### Get the namespace and <application> tags
|
103
|
+
namespace = document.root.namespace_definitions.find { |namespace| namespace.prefix == PWC::PWC_NAMESPACE_PREFIX }
|
104
|
+
application_nodes = document.xpath("//#{PWC::PWC_APPLICATION_ATTRIBUTE}")
|
105
|
+
|
106
|
+
### Verify that the manifest file contains 'android' namespace and <application> tags
|
107
|
+
if namespace.nil? || application_nodes.empty?
|
108
|
+
Playwire::Logger.error("Could not verify 'AndroidManifest.xml' in the project directory. Use --manifest option to define the 'AndroidManifest.xml' path manually.")
|
109
|
+
return
|
110
|
+
end
|
111
|
+
|
112
|
+
### Update or insert <meta-data> tags
|
113
|
+
application_nodes.each { |application|
|
114
|
+
set_metadata_tag(namespace.prefix, application, PWC::PWC_GAD_APP_ID_KEY, gam_app_id)
|
115
|
+
set_metadata_tag(namespace.prefix, application, PWC::PWC_AD_MANAGER_APP_KEY, "true")
|
116
|
+
if is_total_dependency
|
117
|
+
set_activity_tag(namespace.prefix, application, PWC::PWC_AMAZON_AD_ACTIVITY_KEY)
|
118
|
+
set_activity_tag(namespace.prefix, application, PWC::PWC_AMAZON_INTERSTITIAL_ACTIVITY_KEY)
|
119
|
+
end
|
120
|
+
}
|
121
|
+
|
122
|
+
### Update or insert <uses-permission> tags
|
123
|
+
permissions = [
|
124
|
+
PWC::PWC_PERMISSION_INTERNET_KEY,
|
125
|
+
PWC::PWC_PERMISSION_NETWORK_STATE_KEY,
|
126
|
+
PWC::PWC_PERMISSION_WIFI_STATE_KEY,
|
127
|
+
PWC::PWC_PERMISSION_VIBRATE_KEY
|
128
|
+
]
|
129
|
+
|
130
|
+
permissions.each { |permission|
|
131
|
+
set_permission_tag(document, namespace.prefix, permission)
|
132
|
+
}
|
133
|
+
|
134
|
+
### Save changes to the 'AndroidManifest.xml' file
|
135
|
+
begin
|
136
|
+
File.write(File.join(path), document.to_xml)
|
137
|
+
rescue
|
138
|
+
Playwire::Logger.error("Could not write the 'AndroidManifest.xml' file at path #{path}.")
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def parse_manifest_file(path)
|
143
|
+
begin
|
144
|
+
manifest_file = File.join(path)
|
145
|
+
return File.open(manifest_file) { |file| Nokogiri::XML(file) }
|
146
|
+
rescue
|
147
|
+
Playwire::Logger.error("Could not open and read the 'AndroidManifest.xml' file at path #{path}.")
|
148
|
+
return nil
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def set_metadata_tag(namespace_prefix, application_tag, key, value)
|
153
|
+
name_attribute = "#{namespace_prefix}:name"
|
154
|
+
value_attribute = "#{namespace_prefix}:value"
|
155
|
+
|
156
|
+
### Search for <meta-data> tag by name attribute
|
157
|
+
metadata_path = "//#{PWC::PWC_META_DATA_ATTRIBUTE}[@#{name_attribute}=\"#{key}\"]"
|
158
|
+
nodes = application_tag.xpath(metadata_path)
|
159
|
+
|
160
|
+
### Create a new <meta-data> tag with name attribute if it doesn't exist
|
161
|
+
if nodes.empty?
|
162
|
+
metadata = Nokogiri::XML::Node.new PWC::PWC_META_DATA_ATTRIBUTE, application_tag.document
|
163
|
+
metadata[name_attribute] = key
|
164
|
+
metadata.parent = application_tag
|
165
|
+
nodes << metadata
|
166
|
+
end
|
167
|
+
|
168
|
+
### Update the <meta-data> tag with value
|
169
|
+
nodes.each { |node|
|
170
|
+
node[value_attribute] = value
|
171
|
+
}
|
172
|
+
end
|
173
|
+
|
174
|
+
### Add Amazon-related activities
|
175
|
+
def set_activity_tag(namespace_prefix, application_tag, key)
|
176
|
+
name_attribute = "#{namespace_prefix}:name"
|
177
|
+
|
178
|
+
### Search for <activity> tag by name attribute
|
179
|
+
activity_path = "//#{PWC::PWC_ACTIVITY_ATTRIBUTE}[@#{name_attribute}=\"#{key}\"]"
|
180
|
+
nodes = application_tag.xpath(activity_path)
|
181
|
+
|
182
|
+
### Create a new <activity> tag with name attribute if it doesn't exist
|
183
|
+
if nodes.empty?
|
184
|
+
activity = Nokogiri::XML::Node.new PWC::PWC_ACTIVITY_ATTRIBUTE, application_tag.document
|
185
|
+
activity[name_attribute] = key
|
186
|
+
activity.parent = application_tag
|
187
|
+
nodes << activity
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def set_permission_tag(document, namespace_prefix, key)
|
192
|
+
name_attribute = "#{namespace_prefix}:name"
|
193
|
+
|
194
|
+
### Search for <uses-permission> tag by name attribute
|
195
|
+
permission_path = "//#{PWC::PWC_USE_PERMISSION_ATTRIBUTE}[@#{name_attribute}=\"#{key}\"]"
|
196
|
+
nodes = document.xpath(permission_path)
|
197
|
+
|
198
|
+
### Create a new <uses-permission> tag with name attribute if it doesn't exist
|
199
|
+
if nodes.empty?
|
200
|
+
permission = Nokogiri::XML::Node.new PWC::PWC_USE_PERMISSION_ATTRIBUTE, document
|
201
|
+
permission[name_attribute] = key
|
202
|
+
permission.parent = document.root
|
203
|
+
nodes << permission
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
data/lib/playwire/ios.rb
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'set'
|
5
|
+
require 'cocoapods-core'
|
6
|
+
|
7
|
+
require_relative 'pwc'
|
8
|
+
require_relative 'network'
|
9
|
+
require_relative 'logger'
|
10
|
+
require_relative 'plist'
|
11
|
+
|
12
|
+
module Playwire
|
13
|
+
class IOS
|
14
|
+
|
15
|
+
def seek_for_podfile
|
16
|
+
### Looking for the 'Podfile' in the root of project directory
|
17
|
+
podfile_path = Pathname.pwd + 'Podfile'
|
18
|
+
begin
|
19
|
+
### Use 'cocoapods-core' gem to parse the 'Podfile'
|
20
|
+
return Pod::Podfile.from_file(podfile_path)
|
21
|
+
rescue
|
22
|
+
Playwire::Logger.error("No 'Podfile' found in the project directory.")
|
23
|
+
return nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def seek_for_plists(podfile)
|
28
|
+
### Iterate over targets in the 'Podfile' to check which one contains Playwire SDK dependency
|
29
|
+
targets = podfile.target_definition_list.select { |target|
|
30
|
+
target.dependencies.map { |dependency| dependency.name }.count { |name| name =~ /^Playwire.*$/ } > 0
|
31
|
+
}
|
32
|
+
|
33
|
+
### Return error if Playwire SDK dependency hasn't been found
|
34
|
+
if targets.empty?
|
35
|
+
Playwire::Logger.error("No 'Playwire SDK' dependency found in the Podfile.")
|
36
|
+
return nil
|
37
|
+
end
|
38
|
+
|
39
|
+
### Look for 'Info.plist' paths in the targets from the 'Podfile'
|
40
|
+
plists = targets.map { |target|
|
41
|
+
Dir.glob(File.join(Pathname.pwd, '**', '*')).filter { |file| file =~ /.+#{target.name}\/(?!\bPods\b).*\/Info\.plist/ }
|
42
|
+
}.flatten
|
43
|
+
|
44
|
+
### Return error if 'Info.plist' files haven't been found
|
45
|
+
if plists.empty?
|
46
|
+
Playwire::Logger.error("No 'Info.plist' found in the project directory. Use --plist option to define the 'Info.plist' path manually.")
|
47
|
+
return nil
|
48
|
+
end
|
49
|
+
|
50
|
+
return plists
|
51
|
+
end
|
52
|
+
|
53
|
+
def validate_plist_path_from_user(plist_path)
|
54
|
+
### Converts any pathname to an absolute pathname.
|
55
|
+
path = File.expand_path(plist_path, __FILE__)
|
56
|
+
|
57
|
+
### Verify that file exists and the path doesn't point to directory.
|
58
|
+
isExist = File.exist?(path)
|
59
|
+
isDirectory = File.directory?(path)
|
60
|
+
|
61
|
+
### Return error if the file doesn't meet condition.
|
62
|
+
if !isExist || isDirectory
|
63
|
+
Playwire::Logger.error("No a '.plist' file found at the path provided by '--plist'. Check if the '.plist' file exists at the path.")
|
64
|
+
return nil
|
65
|
+
end
|
66
|
+
|
67
|
+
return [path]
|
68
|
+
end
|
69
|
+
|
70
|
+
def load_config_and_set_gam_app_id(publisher_id, app_id, user_plist_path=nil)
|
71
|
+
### Look for the 'Podfile' to confirm Playwire SDK installation
|
72
|
+
podfile = seek_for_podfile()
|
73
|
+
return unless podfile
|
74
|
+
|
75
|
+
### Use 'Info.plist' provided by a pub or looking for 'Info.plist' paths for all targets, which include Playwire SDK
|
76
|
+
plist_paths = user_plist_path.nil? ? seek_for_plists(podfile) : validate_plist_path_from_user(user_plist_path)
|
77
|
+
return unless plist_paths
|
78
|
+
|
79
|
+
### Load config file with metadata provided by a pub or return error if the config file does't exist
|
80
|
+
json = Playwire::Network.load_config(publisher_id, app_id)
|
81
|
+
if json.nil?
|
82
|
+
Playwire::Logger.error("No config file found for the publisher. Check the entered metadata or contact Playwire Account Manager to resolve this issue.")
|
83
|
+
return
|
84
|
+
end
|
85
|
+
|
86
|
+
### Extract 'gamAppId' or return error if the 'gamAppId' is omitted
|
87
|
+
gam_app_id = json.dig('settings', 'gamAppId')
|
88
|
+
if gam_app_id.nil?
|
89
|
+
Playwire::Logger.error("No 'gamAppId' found for the publisher. Contact Playwire Account Manager to resolve this issue.")
|
90
|
+
return
|
91
|
+
end
|
92
|
+
|
93
|
+
plist_paths.each { |path|
|
94
|
+
### Open and read the 'Info.plist' file
|
95
|
+
plist = Playwire::Plist.read(path)
|
96
|
+
if plist.nil?
|
97
|
+
Playwire::Logger.error("Could not read the 'Info.plist' file at path #{path}.")
|
98
|
+
return
|
99
|
+
end
|
100
|
+
|
101
|
+
### Insert 'gamAppId' to the 'Info.plist' file
|
102
|
+
plist[Playwire::PWC::Plist::PWC_GAD_APP_ID_KEY] = gam_app_id
|
103
|
+
### Save the modified 'Info.plist' file
|
104
|
+
Playwire::Plist.write(plist, path)
|
105
|
+
}
|
106
|
+
|
107
|
+
Playwire::Logger.success("The 'Info.plist' has been updated with 'gamAppId' = #{gam_app_id}.")
|
108
|
+
end
|
109
|
+
|
110
|
+
def load_skadnetwork_and_set_to_info_plist(user_plist_path=nil)
|
111
|
+
### Look for the 'Podfile' to confirm Playwire SDK installation
|
112
|
+
podfile = seek_for_podfile()
|
113
|
+
return unless podfile
|
114
|
+
|
115
|
+
### Use 'Info.plist' provided by a pub or looking for 'Info.plist' paths for all targets, which include Playwire SDK
|
116
|
+
plist_paths = user_plist_path.nil? ? seek_for_plists(podfile) : validate_plist_path_from_user(user_plist_path)
|
117
|
+
return unless plist_paths
|
118
|
+
|
119
|
+
### Load JSON with SKAdNetwork items or return error if such JSON file does't exist
|
120
|
+
json = Playwire::Network.load_sk_ad_network_items()
|
121
|
+
if json.nil?
|
122
|
+
Playwire::Logger.error("No SKAdNetwork items found. Contact Playwire tech team to resolve this issue.")
|
123
|
+
return
|
124
|
+
end
|
125
|
+
|
126
|
+
### Create SKAdNetwork items set to avoid duplicates
|
127
|
+
fetched_ids = json[Playwire::PWC::Plist::PWC_SK_AD_NETWORK_ITEMS_KEY].to_set
|
128
|
+
|
129
|
+
plist_paths.each { |path|
|
130
|
+
### Open and read the 'Info.plist' file
|
131
|
+
plist = Playwire::Plist.read(path)
|
132
|
+
if plist.nil?
|
133
|
+
Playwire::Logger.error("Could not read the 'Info.plist' file at path #{path}.")
|
134
|
+
return
|
135
|
+
end
|
136
|
+
|
137
|
+
### Read existing SKAdNetwork items from the 'Info.plist' file
|
138
|
+
ad_network_items = plist[Playwire::PWC::Plist::PWC_SK_AD_NETWORK_ITEMS_KEY] || []
|
139
|
+
existing_ids = ad_network_items.map { |item| item[Playwire::PWC::Plist::PWC_SK_AD_NETWORK_ID_KEY] }.compact.to_set
|
140
|
+
|
141
|
+
### Merge existing SKAdNetwork items with downloaded ones and insert to the 'Info.plist' file
|
142
|
+
ad_network_ids = (existing_ids + fetched_ids).map { |id| {Playwire::PWC::Plist::PWC_SK_AD_NETWORK_ID_KEY => id } }
|
143
|
+
plist[Playwire::PWC::Plist::PWC_SK_AD_NETWORK_ITEMS_KEY] = ad_network_ids
|
144
|
+
|
145
|
+
### Save the modified 'Info.plist' file
|
146
|
+
Playwire::Plist.write(plist, path)
|
147
|
+
}
|
148
|
+
|
149
|
+
Playwire::Logger.success("The 'Info.plist' has been updated with SKAdNetwork items.")
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'colorize'
|
2
|
+
|
3
|
+
module Playwire
|
4
|
+
|
5
|
+
class Logger
|
6
|
+
def self.error(message)
|
7
|
+
puts "[✖] #{message}".red
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.warning(message)
|
11
|
+
puts "[!] #{message}".yellow
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.success(message)
|
15
|
+
puts "[✔︎] #{message}".green
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.red(message)
|
19
|
+
puts message.red
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'net/http'
|
3
|
+
require 'json'
|
4
|
+
require_relative 'logger'
|
5
|
+
require_relative 'uri_builder'
|
6
|
+
|
7
|
+
module Playwire
|
8
|
+
class Network
|
9
|
+
|
10
|
+
def self.load_config(publisher_id, app_id)
|
11
|
+
uri = Playwire::URIBuilder::config_file(publisher_id, app_id)
|
12
|
+
return load_json(uri)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.load_sk_ad_network_items
|
16
|
+
uri = Playwire::URIBuilder::sk_ad_network_items()
|
17
|
+
return load_json(uri)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.load_json(uri)
|
21
|
+
begin
|
22
|
+
res = Net::HTTP.get_response(uri)
|
23
|
+
return res.is_a?(Net::HTTPSuccess) ? JSON.parse(res.body) : nil
|
24
|
+
rescue => error
|
25
|
+
Playwire::Logger.error("#{error.message}")
|
26
|
+
return nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'xcodeproj'
|
2
|
+
require_relative 'logger'
|
3
|
+
|
4
|
+
module Playwire
|
5
|
+
class Plist
|
6
|
+
|
7
|
+
def self.read(path)
|
8
|
+
begin
|
9
|
+
return Xcodeproj::Plist.read_from_path(path)
|
10
|
+
rescue
|
11
|
+
return nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.write(data, path)
|
16
|
+
begin
|
17
|
+
Xcodeproj::Plist.write_to_path(data, path)
|
18
|
+
rescue Xcodeproj::Informative => error
|
19
|
+
Playwire::Logger.red(error.message)
|
20
|
+
rescue
|
21
|
+
Playwire::Logger.error("Could not write the 'Info.plist' file at path #{path}.")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/playwire/pwc.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
module Playwire
|
2
|
+
class PWC
|
3
|
+
class Config
|
4
|
+
PW_RAMP_HOST = 'config.playwire.com'
|
5
|
+
PW_RAMP_APPS_PATH = 'apps'
|
6
|
+
PW_RAMP_FILE_PATH = 'config'
|
7
|
+
end
|
8
|
+
|
9
|
+
class SK_Ad_Network
|
10
|
+
PW_S3_HOST = 'app.intergient.com'
|
11
|
+
PW_S3_PATH = 'skadnetworkitems'
|
12
|
+
PW_S3_FILE_PATH = 'skadnetworkitems'
|
13
|
+
end
|
14
|
+
|
15
|
+
class Plist
|
16
|
+
PWC_SK_AD_NETWORK_ITEMS_KEY = 'SKAdNetworkItems'
|
17
|
+
PWC_SK_AD_NETWORK_ID_KEY = 'SKAdNetworkIdentifier'
|
18
|
+
PWC_GAD_APP_ID_KEY = 'GADApplicationIdentifier'
|
19
|
+
end
|
20
|
+
|
21
|
+
class AndroidManifest
|
22
|
+
PWC_NAMESPACE_PREFIX = 'android'
|
23
|
+
PWC_APPLICATION_ATTRIBUTE = 'application'
|
24
|
+
PWC_META_DATA_ATTRIBUTE = 'meta-data'
|
25
|
+
PWC_USE_PERMISSION_ATTRIBUTE = 'uses-permission'
|
26
|
+
PWC_ACTIVITY_ATTRIBUTE = 'activity'
|
27
|
+
PWC_GAD_APP_ID_KEY = 'com.google.android.gms.ads.APPLICATION_ID'
|
28
|
+
PWC_AD_MANAGER_APP_KEY = 'com.google.android.gms.ads.AD_MANAGER_APP'
|
29
|
+
PWC_PERMISSION_INTERNET_KEY = 'android.permission.INTERNET'
|
30
|
+
PWC_PERMISSION_NETWORK_STATE_KEY = 'android.permission.ACCESS_NETWORK_STATE'
|
31
|
+
PWC_PERMISSION_WIFI_STATE_KEY = 'android.permission.ACCESS_WIFI_STATE'
|
32
|
+
PWC_PERMISSION_VIBRATE_KEY = 'android.permission.VIBRATE'
|
33
|
+
PWC_AMAZON_AD_ACTIVITY_KEY = 'com.amazon.device.ads.DTBAdActivity'
|
34
|
+
PWC_AMAZON_INTERSTITIAL_ACTIVITY_KEY = 'com.amazon.device.ads.DTBInterstitialActivity'
|
35
|
+
PWC_COPPA_DEPENDENCY = 'com.intergi.playwire:playwiresdk_coppa'
|
36
|
+
PWC_TOTAL_DEPENDENCY = 'com.intergi.playwire:playwiresdk_total'
|
37
|
+
end
|
38
|
+
|
39
|
+
PW_JSON_FILE_EXTENSION = 'json'
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require_relative 'pwc'
|
3
|
+
|
4
|
+
module Playwire
|
5
|
+
class URIBuilder
|
6
|
+
|
7
|
+
PWC = Playwire::PWC
|
8
|
+
PWC_CONFIG = PWC::Config
|
9
|
+
PWC_SK_AD_NETWORK = PWC::SK_Ad_Network
|
10
|
+
|
11
|
+
def self.config_file(publisher_id, app_id)
|
12
|
+
file_path = "#{PWC_CONFIG::PW_RAMP_FILE_PATH}.#{PWC::PW_JSON_FILE_EXTENSION}"
|
13
|
+
path = "/#{publisher_id}/#{PWC_CONFIG::PW_RAMP_APPS_PATH}/#{app_id}/#{file_path}"
|
14
|
+
return URI::HTTPS.build(host: PWC_CONFIG::PW_RAMP_HOST, path: path)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.sk_ad_network_items
|
18
|
+
file_path = "#{PWC_SK_AD_NETWORK::PW_S3_FILE_PATH}.#{PWC::PW_JSON_FILE_EXTENSION}"
|
19
|
+
path = "/#{PWC_SK_AD_NETWORK::PW_S3_PATH}/#{file_path}"
|
20
|
+
return URI::HTTPS.build(host: PWC_SK_AD_NETWORK::PW_S3_HOST, path: path)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/playwire.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'set'
|
5
|
+
require 'cocoapods-core'
|
6
|
+
|
7
|
+
require_relative 'playwire/pwc'
|
8
|
+
require_relative 'playwire/network'
|
9
|
+
require_relative 'playwire/logger'
|
10
|
+
require_relative 'playwire/plist'
|
11
|
+
require_relative 'playwire/ios'
|
12
|
+
require_relative 'playwire/android'
|
13
|
+
|
14
|
+
module Playwire
|
15
|
+
class Command
|
16
|
+
|
17
|
+
class Android
|
18
|
+
def self.load_config_and_set_gam_app_id(publisher_id, app_id, user_manifest_path)
|
19
|
+
Playwire::Android.new.load_config_and_set_gam_app_id(
|
20
|
+
publisher_id,
|
21
|
+
app_id,
|
22
|
+
user_manifest_path
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class IOS
|
28
|
+
def self.load_config_and_set_gam_app_id(publisher_id, app_id, user_plist_path)
|
29
|
+
Playwire::IOS.new.load_config_and_set_gam_app_id(
|
30
|
+
publisher_id,
|
31
|
+
app_id,
|
32
|
+
user_plist_path
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.load_skadnetwork_and_set_to_info_plist(user_plist_path)
|
37
|
+
Playwire::IOS.new.load_skadnetwork_and_set_to_info_plist(user_plist_path)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
metadata
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: playwire
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Playwire Mobile Team
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-03-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: xcodeproj
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.20'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.20'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: thor
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.2.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.2.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: cocoapods-core
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.11'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.11'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: colorize
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.8.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.8.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: nokogiri
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.14.0
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.14.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: bundler
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 2.2.8
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 2.2.8
|
97
|
+
description: Playwire CLI (Command Line Interface) to achieve common tasks while using
|
98
|
+
Playwire products.
|
99
|
+
email:
|
100
|
+
- dev@playwire.com
|
101
|
+
executables:
|
102
|
+
- playwire
|
103
|
+
extensions: []
|
104
|
+
extra_rdoc_files: []
|
105
|
+
files:
|
106
|
+
- CHANGELOG.md
|
107
|
+
- LICENSE.txt
|
108
|
+
- README.md
|
109
|
+
- bin/playwire
|
110
|
+
- lib/playwire.rb
|
111
|
+
- lib/playwire/android.rb
|
112
|
+
- lib/playwire/ios.rb
|
113
|
+
- lib/playwire/logger.rb
|
114
|
+
- lib/playwire/network.rb
|
115
|
+
- lib/playwire/plist.rb
|
116
|
+
- lib/playwire/pwc.rb
|
117
|
+
- lib/playwire/uri_builder.rb
|
118
|
+
- lib/playwire/version.rb
|
119
|
+
homepage: https://www.playwire.com
|
120
|
+
licenses:
|
121
|
+
- MIT
|
122
|
+
metadata: {}
|
123
|
+
post_install_message:
|
124
|
+
rdoc_options: []
|
125
|
+
require_paths:
|
126
|
+
- lib
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 2.4.0
|
132
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
requirements: []
|
138
|
+
rubygems_version: 3.1.2
|
139
|
+
signing_key:
|
140
|
+
specification_version: 4
|
141
|
+
summary: Wizard automating tasks on Playwire products.
|
142
|
+
test_files: []
|