Skip to content

Commit 906b988

Browse files
committed
Adds Creative Cloud helper commands
1 parent 7be0bce commit 906b988

File tree

10 files changed

+892
-2
lines changed

10 files changed

+892
-2
lines changed

bin/console

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ use DevCoding\Mac\Command as Command;
1212
$command[] = new Command\DockImportCommand();
1313
$command[] = new Command\DockDumpCommand();
1414
$command[] = new Command\DefaultApplicationCommand();
15-
$app = new Application('MacPrefer', 'v1.0');
15+
$command[] = new Command\AdobeInfoCommand();
16+
$command[] = new Command\AdobeBackupCommand();
17+
$command[] = new Command\AdobeTransferCommand();
18+
$app = new Application('MacPrefer', 'v1.2');
1619
$app->addCommands($command);
1720
$app->run();

box.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
"name": "*.php",
1212
"exclude": ["Tests"],
1313
"in": "vendor"
14+
},
15+
{
16+
"name": "cc.json",
17+
"in": "resources/config"
1418
}
1519
],
1620
"git-version": "package_version",

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414
"email": "aaron@jonesicoding.com"
1515
}
1616
],
17-
"version": "1.0",
17+
"version": "1.2",
1818
"require": {
1919
"ext-json": "*",
20+
"ext-posix": "*",
2021
"symfony/yaml": "^4.4",
2122
"symfony/console": "^4.4",
2223
"jonesiscoding/base-console": "^1.0",

dist/prefer.phar

112 KB
Binary file not shown.

resources/config/cc.json

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"illustrator": {
3+
"sap": "ILST",
4+
"names": [ "Illustrator", "Illustrator CC" ],
5+
"preferences": ["Library/Preferences/Adobe Illustrator {version}"],
6+
"path": "Adobe Illustrator {year}/Adobe Illustrator.app",
7+
"baseVersions": {
8+
"22.0": "2018",
9+
"23.0": "2019",
10+
"24.0": "2020",
11+
"25.0": "2021"
12+
}
13+
},
14+
"indesign": {
15+
"sap": "IDSN",
16+
"names": [ "InDesign", "InDesign CC" ],
17+
"path": "Adobe InDesign {year}/Adobe InDesign {year}.app",
18+
"preferences": ["Library/Preferences/Adobe InDesign/Version {version}"],
19+
"baseVersions": {
20+
"13.0": "2018",
21+
"14.0": "2019",
22+
"15.0": "2020",
23+
"16.0": "2021"
24+
}
25+
},
26+
"photoshop": {
27+
"sap": "PSHP",
28+
"names": [ "Photoshop", "Photoshop CC" ],
29+
"path": "Adobe {name} {year}/Adobe {name} {year}.app",
30+
"preferences": [
31+
"Library/Preferences/Adobe {name} {year} Settings",
32+
"Library/Preferences/Adobe {name} {year} Paths"
33+
],
34+
"baseVersions": {
35+
"13.0": "2018",
36+
"14.0": "2019",
37+
"15.0": "2020",
38+
"16.0": "2021"
39+
}
40+
}
41+
}
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
<?php
2+
3+
4+
namespace DevCoding\Mac\Command;
5+
6+
7+
use DevCoding\Command\Base\AbstractMacConsole;
8+
use DevCoding\Mac\Objects\CreativeCloudApp;
9+
use Symfony\Component\Console\Input\InputInterface;
10+
use Symfony\Component\Console\Input\InputOption;
11+
use Symfony\Component\Console\Output\OutputInterface;
12+
13+
class AbstractAdobeConsole extends AbstractMacConsole
14+
{
15+
public function configure()
16+
{
17+
$this->addOption('user', 'u', InputOption::VALUE_REQUIRED, 'The user to run the command for. Defaults to current user.');
18+
}
19+
20+
public function interact(InputInterface $input, OutputInterface $output)
21+
{
22+
if ($input->hasOption('user'))
23+
{
24+
if ($user = $input->getOption('user'))
25+
{
26+
$this->setUser($user);
27+
}
28+
}
29+
}
30+
31+
/**
32+
* @param $app
33+
* @param null $year
34+
*
35+
* @return CreativeCloudApp
36+
*/
37+
protected function getCreativeCloudApp($app, $year = null)
38+
{
39+
return $year ? new CreativeCloudApp($app, $year) : new CreativeCloudApp($app);
40+
}
41+
42+
protected function getBackupPath($app, $year = null)
43+
{
44+
if ($year)
45+
{
46+
return sprintf("%s/Preferences/Prefer/CC/%s/%s", $this->getUserLibraryDir(), $app, $year);
47+
}
48+
else
49+
{
50+
return sprintf("%s/Preferences/Prefer/CC/%s", $this->getUserLibraryDir(), $app);
51+
}
52+
}
53+
54+
/**
55+
* @param CreativeCloudApp $ccApp
56+
* @param $dest
57+
*
58+
* @return bool
59+
*/
60+
protected function doPreferenceBackup(CreativeCloudApp $ccApp, $dest)
61+
{
62+
$dest = $dest . '/tmp';
63+
if (!is_dir($dest))
64+
{
65+
if (!file_exists($dest))
66+
{
67+
@mkdir($dest, 0777, true);
68+
}
69+
else
70+
{
71+
throw new \Exception('Could not create backup destination directory');
72+
}
73+
}
74+
75+
$userDir = $this->getUserDir();
76+
foreach($ccApp->getPreferences() as $preference)
77+
{
78+
$path = sprintf("%s/%s", $userDir, $preference);
79+
if (file_exists($path))
80+
{
81+
$cmd = sprintf('rsync -aP --ignore-times "%s" "%s/"',$path,$dest);
82+
exec($cmd,$output,$retval);
83+
if ($retval !== 0)
84+
{
85+
throw new \Exception('An error was encountered backing up preferences: ');
86+
}
87+
}
88+
}
89+
90+
$date = date( 'Ymd-Hi' );
91+
$zipFile = sprintf( 'backup-%s.zip', $date );
92+
$zipPath = dirname($dest) . '/' . $zipFile;
93+
$cmd = sprintf( 'cd "%s" && zip -r "%s" ./* && cd -', $dest, $zipPath );
94+
exec( $cmd,$output, $retval );
95+
if( $retval || !file_exists( $zipPath ) )
96+
{
97+
throw new \Exception( "Could not compress the backup after copying." );
98+
}
99+
else
100+
{
101+
$this->rrmdir($dest);
102+
}
103+
104+
return true;
105+
}
106+
107+
private function rrmdir($src)
108+
{
109+
if (is_dir($src))
110+
{
111+
$inTmp = (strpos($src, '/tmp') === 0 && $src !== '/tmp');
112+
$inUser = (strpos($src, $this->getUserDir()) === 0 && $src !== $this->getUserDir());
113+
114+
if (!$inTmp && !$inUser)
115+
{
116+
throw new \Exception(sprintf('The directory "%s" cannot be deleted with this application.',$src));
117+
}
118+
119+
$dir = opendir($src);
120+
while(false !== ( $file = readdir($dir)) ) {
121+
if (( $file != '.' ) && ( $file != '..' )) {
122+
$full = $src . '/' . $file;
123+
if ( is_dir($full) ) {
124+
$this->rrmdir($full);
125+
}
126+
else {
127+
unlink($full);
128+
}
129+
}
130+
}
131+
closedir($dir);
132+
rmdir($src);
133+
}
134+
}
135+
136+
private function rcopy( $src, $dst )
137+
{
138+
if (!is_dir($dst))
139+
{
140+
@mkdir( $dst );
141+
}
142+
143+
if (is_dir($src))
144+
{
145+
$dir = opendir( $src );
146+
while( false !== ( $file = readdir( $dir ) ) )
147+
{
148+
if( ( $file != '.' ) && ( $file != '..' ) )
149+
{
150+
if( is_dir( $src . '/' . $file ) )
151+
{
152+
$this->rcopy( $src . '/' . $file, $dst . '/' . $file );
153+
}
154+
else
155+
{
156+
if( !copy( $src . '/' . $file, $dst . '/' . $file ) )
157+
{
158+
throw new \Exception( "Could not copy\n" . $src . "\nto\n" . $dst );
159+
}
160+
}
161+
}
162+
}
163+
closedir( $dir );
164+
}
165+
elseif(is_file($src))
166+
{
167+
copy($src, $dst.'/');
168+
}
169+
}
170+
}

src/Command/AdobeBackupCommand.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
4+
namespace DevCoding\Mac\Command;
5+
6+
7+
use DevCoding\Command\Base\AbstractConsole;
8+
use DevCoding\Mac\Objects\CreativeCloudApp;
9+
use Symfony\Component\Console\Command\Command;
10+
use Symfony\Component\Console\Input\InputArgument;
11+
use Symfony\Component\Console\Input\InputInterface;
12+
use Symfony\Component\Console\Input\InputOption;
13+
use Symfony\Component\Console\Output\OutputInterface;
14+
15+
class AdobeBackupCommand extends AbstractAdobeConsole
16+
{
17+
public function configure()
18+
{
19+
$this->setName('adobe:backup');
20+
$this->setDescription('Backs up the preferences of an Adobe Creative Cloud application.');
21+
$this->addArgument('application', InputArgument::REQUIRED);
22+
$this->addArgument('year', InputArgument::OPTIONAL);
23+
24+
parent::configure();
25+
}
26+
27+
public function execute(InputInterface $input, OutputInterface $output)
28+
{
29+
$app = strtolower(str_replace(" ", "-", $this->io()->getArgument('application')));
30+
$year = $this->io()->getArgument('year');
31+
$ccApp = $this->getCreativeCloudApp($app, $year);
32+
$this->io()->blankln();
33+
34+
$this->io()->msg('Locating Adobe Application', 50);
35+
if ($ccApp->getPath())
36+
{
37+
$this->io()->successln('[DONE]');
38+
39+
try
40+
{
41+
$this->io()->msg('Backing Up '.$ccApp->getFullName().' Preferences',50);
42+
$this->doPreferenceBackup($ccApp, $this->getBackupPath($app, $year));
43+
$this->io()->successln('[DONE]');
44+
}
45+
catch(\Exception $e)
46+
{
47+
$this->io()->errorln('[ERROR]');
48+
$this->io()->errorblk($e->getMessage());
49+
50+
return self::EXIT_ERROR;
51+
}
52+
}
53+
else
54+
{
55+
$this->io()->errorln('[ERROR]');
56+
57+
$this->io()->errorblk('Could not locate the requested application.');
58+
59+
return self::EXIT_ERROR;
60+
}
61+
62+
return self::EXIT_SUCCESS;
63+
}
64+
}

src/Command/AdobeInfoCommand.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
4+
namespace DevCoding\Mac\Command;
5+
6+
7+
use DevCoding\Command\Base\AbstractConsole;
8+
use DevCoding\Mac\Objects\CreativeCloudApp;
9+
use Symfony\Component\Console\Command\Command;
10+
use Symfony\Component\Console\Input\InputArgument;
11+
use Symfony\Component\Console\Input\InputInterface;
12+
use Symfony\Component\Console\Input\InputOption;
13+
use Symfony\Component\Console\Output\OutputInterface;
14+
15+
class AdobeInfoCommand extends AbstractAdobeConsole
16+
{
17+
public function configure()
18+
{
19+
$this->setName('adobe:info');
20+
$this->setDescription('Provides information about the installed Adobe application, in JSON format.');
21+
$this->addArgument('application', InputArgument::REQUIRED);
22+
$this->addArgument('year', InputArgument::OPTIONAL);
23+
}
24+
25+
public function execute(InputInterface $input, OutputInterface $output)
26+
{
27+
$app = strtolower(str_replace(" ", "-", $this->io()->getArgument('application')));
28+
$year = $this->io()->getArgument('year');
29+
$ccApp = $this->getCreativeCloudApp($app, $year);
30+
31+
if ($ccApp->getPath())
32+
{
33+
$this->io()->writeln(json_encode($ccApp, JSON_PRETTY_PRINT+JSON_UNESCAPED_SLASHES));
34+
}
35+
else
36+
{
37+
echo "{}";
38+
}
39+
40+
return self::EXIT_SUCCESS;
41+
}
42+
}

0 commit comments

Comments
 (0)