Skip to content

Commit c8aaafc

Browse files
committed
upgraded Laravel to 6.0 and other dependencies too while trying to improve code to handle options and errors more gracefully (see #7)(see #8)(see #9)
1 parent 1b02f0e commit c8aaafc

File tree

4 files changed

+203
-44
lines changed

4 files changed

+203
-44
lines changed

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ Allows you to export JSON files of your most important data (questions, answers,
55

66
1. I think this project requires PHP 7.3 or later, so be sure that your system complies.
77
1. Sign up at https://stackapps.com/apps/oauth/register to receive a Client ID, Client Secret, and Key. (It's free, easy, and fast.)
8-
1. Create a Laravel project, and make sure that it works: https://laravel.com/docs/5.8/installation#installing-laravel
9-
1. Add this package into your Laravel project: `vagrant@vboxHomestead:~/Code/MyLaravelProject$ composer require ryancwalsh/stack-exchange-backup-laravel:dev-master --prefer-source`
8+
1. Create a Laravel project, and make sure that it works: https://laravel.com/docs/6.0/installation
9+
1. Add this package into your Laravel project: `vagrant@vboxHomestead:~/Code/MyLaravelProject$ composer require ryancwalsh/stack-exchange-backup-laravel:^2.0.0`
1010
1. Run `php artisan vendor:publish`, and if it gives you a choice, choose to publish from this package.
1111
1. Edit your Laravel project's `.env` file to have your own StackApps values. A non-working sample is below.
12-
1. Run `php artisan exportStackExchange`. (Note that `php artisan exportStackExchange --flushCache` is an available option to clear the cached access code value.)
12+
1. Run `php artisan exportStackExchange`. There are also these options available:
13+
1. `php artisan exportStackExchange --forgetCache` is an available option to clear the cached access code value.
14+
1. `php artisan exportStackExchange --code=YOUR_CODE` is an available option to provide a code that you've already retrieved from StackExchange.
15+
1. `php artisan exportStackExchange --S3=false` is an available option to skip uploading to Amazon S3.
1316
1. Following the instructions in the terminal, you'll use your browser to visit a URL that will provide you with a temporary access token to paste into the terminal.
14-
1. Finished! The JSON files will appear in your `/storage/app/StackExchange` folder.
17+
1. Finished! The JSON files will appear in your `/storage/app/StackExchange` folder, and a zip of those files will appear in S3.
1518

1619
```
1720
# These are sample .env values:

composer.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22
"name": "ryancwalsh/stack-exchange-backup-laravel",
33
"description": "My aim is to back up all of my questions and answers and anything else valuable in my accounts across all of the StackExchange sites (StackOverflow, SuperUser, https://apple.stackexchange.com/, https://askubuntu.com/, etc).",
44
"type": "package",
5+
"version": "2.0.0",
56
"require": {
67
"guzzlehttp/guzzle": "^6.3",
7-
"php": "^7.2",
8-
"laravel/framework": "^5.6",
9-
"league/flysystem-aws-s3-v3": "^1.0"
8+
"php": "^7.3",
9+
"laravel/framework": "6.0.*",
10+
"laravel/helpers": "^1.1",
11+
"league/flysystem-aws-s3-v3": "^1.0",
12+
"spatie/laravel-backup": "^6.4"
1013
},
1114
"autoload": {
1215
"psr-4": {

src/ExportStackExchangeCommand.php

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,20 @@
55
use Cache;
66
use Carbon\Carbon;
77
use Illuminate\Console\Command;
8+
use Log;
89

910
class ExportStackExchangeCommand extends Command {
1011

1112
const CODE_CACHE_KEY = 'stackAppsCode';
12-
const FILENAME_SAFE_FORMAT = "Y-m-d_His_T";
13+
const ENDPOINTS = ['answers' => 'activity', 'questions' => 'activity', 'comments' => 'creation', 'mentioned' => 'creation', 'favorites' => 'creation'];
14+
const SE_URL_BEGINNING = 'https://stackexchange.com/oauth/login_success?code=';
1315

1416
/**
1517
* The name and signature of the console command.
1618
*
1719
* @var string
1820
*/
19-
protected $signature = 'exportStackExchange {--code=} {--flushCache}';
21+
protected $signature = 'exportStackExchange {--code=} {--S3=true} {--forgetCache}';
2022

2123
/**
2224
* The console command description.
@@ -28,7 +30,7 @@ class ExportStackExchangeCommand extends Command {
2830

2931
public function __construct() {
3032
parent::__construct();
31-
$this->exportStackExchangeHelper = new ExportStackExchangeHelper();
33+
$this->exportStackExchangeHelper = new ExportStackExchangeHelper();
3234
}
3335

3436
/**
@@ -38,26 +40,48 @@ public function __construct() {
3840
*/
3941
public function handle() {
4042
$this->exportStackExchangeHelper->setConsoleOutput($this->getOutput());
41-
if ($this->option('flushCache')) {
42-
Cache::flush();
43+
$this->handleForgetCacheOption();
44+
try {
45+
$this->handleStackExchangeCode();
46+
$this->info(Carbon::now() . ' Starting.');
47+
$this->exportStackExchangeHelper->setMomentString(Carbon::now()->format(\App\Helpers\ExtraTools::FILENAME_SAFE_FORMAT));
48+
$mySites = $this->exportStackExchangeHelper->getMyAssociatedSites();
49+
$this->showListOfMySites($mySites);
50+
$this->info('===');
51+
$this->exportEachSite($mySites);
52+
if ($this->option('S3') === 'true') {//https://stackoverflow.com/a/7336873/470749
53+
$this->exportStackExchangeHelper->archiveToS3();
54+
} else {
55+
$this->info('(Skipping S3 upload due to S3=false option.)');
56+
}
57+
} catch (\Exception $e) {
58+
Log::error(__CLASS__ . ' ' . __FUNCTION__ . ' ' . $e);
59+
$this->error('Error. Check the Laravel log (probably at /storage/logs/laravel.log).');
4360
}
61+
$this->info(Carbon::now() . ' Finished.');
62+
}
63+
64+
public function handleForgetCacheOption() {
65+
if ($this->option('forgetCache')) {
66+
Cache::forget(self::CODE_CACHE_KEY);
67+
Cache::forget($this->exportStackExchangeHelper::ACCESS_TOKEN_CACHE_KEY);
68+
$this->info('Cleared cache values.');
69+
}
70+
}
71+
72+
public function handleStackExchangeCode() {
4473
$code = $this->option('code') ?? Cache::get(self::CODE_CACHE_KEY);
45-
if (!$code) {
74+
if (!$code) {//If code wasn't provided via option and wasn't available from cache, explain the process for fetching a code in the browser.
4675
$url = $this->exportStackExchangeHelper->getOauthUrl();
4776
$this->info('Visit ' . $url);
48-
$code = $this->ask('Then, the browser will bounce to a new URL, which will contain a `code` parameter at the end. Copy the value of just the `code` parameter from the URL. Paste it here:');
77+
$codePasted = $this->ask('Then, the browser will bounce to a new URL. Copy the value of the `code` parameter in the URL. Paste it here:');
78+
$code = str_replace(self::SE_URL_BEGINNING, '', $codePasted); //just in case the user accidentally pasted the entire URL instead of just the `code` parameter.
79+
Log::debug('$code=' . $code);
4980
Cache::put(self::CODE_CACHE_KEY, $code, $this->exportStackExchangeHelper::SESSION_MINS);
5081
Cache::forget($this->exportStackExchangeHelper::ACCESS_TOKEN_CACHE_KEY);
5182
$this->info('Code now saved to cache for ' . $this->exportStackExchangeHelper::SESSION_MINS . ' minutes: ' . Cache::get(self::CODE_CACHE_KEY));
5283
}
5384
$this->exportStackExchangeHelper->setCode($code);
54-
$this->info(Carbon::now() . ' Starting.');
55-
$this->exportStackExchangeHelper->setFilenamePrefix('StackExchange/' . Carbon::now()->format(self::FILENAME_SAFE_FORMAT) . '/');
56-
$mySites = $this->exportStackExchangeHelper->getMyAssociatedSites();
57-
$this->showListOfMySites($mySites);
58-
$this->info('===');
59-
$this->exportEachSite($mySites);
60-
$this->info(Carbon::now() . ' Finished.');
6185
}
6286

6387
/**
@@ -71,15 +95,19 @@ public function handle() {
7195
* @param array $mySites
7296
*/
7397
public function exportEachSite($mySites) {
98+
$bar = $this->output->createProgressBar(count($mySites)); //https://laravel.com/docs/6.0/artisan#writing-output
99+
$bar->start();
74100
foreach ($mySites as $site) {
75101
$this->showDetailsOfThisSite($site);
76102
$sitesToExclude = []; //['Stack Overflow', 'Server Fault', 'Super User'];
77-
if (!in_array($site['site_name'], $sitesToExclude)) {
78-
foreach (['answers' => 'activity', 'questions' => 'activity', 'comments' => 'creation', 'mentioned' => 'creation', 'favorites' => 'creation'] as $endpoint => $sort) {
103+
if (!in_array($site['site_name'], $sitesToExclude)) {
104+
foreach (self::ENDPOINTS as $endpoint => $sort) {
79105
$this->exportStackExchangeHelper->saveJsonFromApi($endpoint, $site, $sort);
80106
}
81107
}
108+
$bar->advance();
82109
}
110+
$bar->finish();
83111
}
84112

85113
/**

0 commit comments

Comments
 (0)