Last active
April 4, 2020 21:22
-
-
Save shiena/ccbb5f2a382cc16b616b5848594539c1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# for post article | |
$devToApiKey = 'your-dev.to-api-key' | |
# for image upload | |
$UserName = 'your-dev.to-username' | |
$Password = 'your-dev.to-password' | |
$seleniumHome = 'your-selenium-path' | |
$blackListTags = @() | |
# nuget install Selenium.WebDriver.ChromeDriver | |
# nuget install Selenium.WebDriver | |
# nuget install Selenium.Support | |
$webDriverDllPath = Convert-Path (Join-Path $seleniumHome '\Selenium.WebDriver.3.141.0\lib\netstandard2.0\WebDriver.dll') | |
$WebDriverSupportDllPath = Convert-Path (Join-Path $seleniumHome '\Selenium.Support.3.141.0\lib\netstandard2.0\WebDriver.Support.dll') | |
$chromeDriverDirPath = Convert-Path (Join-Path $seleniumHome '\Selenium.WebDriver.ChromeDriver.80.0.3987.10600\driver\win32') | |
if (!(Test-Path -Path $webDriverDllPath -PathType Leaf)) { | |
Write-Host "Not exists WebDriver.dll" | |
Return | |
} | |
if (!(Test-Path -Path $WebDriverSupportDllPath -PathType Leaf)) { | |
Write-Host "Not Exists WebDriver.Support.dll" | |
Return | |
} | |
if (!(Test-Path -Path $chromeDriverDirPath -PathType Container)) { | |
Write-Host "Not Exists chromedriver folder" | |
Return | |
} | |
#dll読み込み | |
Add-Type -Path $webDriverDllPath | |
Add-Type -Path $WebDriverSupportDllPath | |
#chrome起動 | |
$chromeDriver = New-Object OpenQA.Selenium.Chrome.ChromeDriver($chromeDriverDirPath) | |
#URL開く | |
#dev.toのGitHub連携のサインインページを開く | |
$chromeDriver.Url = "https://dev.to/users/auth/github?state=navbar_basic" | |
#dev.toにログインする | |
$chromeDriver.FindElementById("login_field").SendKeys($UserName) | |
$chromeDriver.FindElementById("password").SendKeys($Password) | |
$chromeDriver.FindElementByName("commit").Submit() | |
#dev.toにログインするまで待つ | |
$webDriverWait = New-Object OpenQA.Selenium.Support.UI.WebDriverWait($chromeDriver , (New-TimeSpan -Seconds 10)) | |
$webDriverWait.Until([OpenQA.Selenium.Support.UI.ExpectedConditions]::TitleContains("Dashboard")) | |
Get-ChildItem -Path . -Directory | | |
Select-Object @{ Label = 'item'; Expression = { $_.FullName } }, | |
@{ Label = 'images'; Expression = { Get-ChildItem -Path $_.FullName -File -Recurse -Exclude '*.md', '*.json' } } | | |
Where-Object { | |
(Test-Path -Path (Join-Path $_.item 'meta.json') -PathType Leaf) -And | |
(Test-Path -Path (Join-Path $_.item 'readme.md') -PathType Leaf) | |
} | | |
Sort-Object { [DateTime](Get-Content (Join-Path $_.item 'meta.json') | ConvertFrom-Json).created_at } | | |
Select-Object @{ | |
Label = 'request'; | |
Expression = { | |
$meta = Get-Content (Join-Path $_.item 'meta.json') | ConvertFrom-Json | |
[System.Console]::WriteLine("start $($meta.title)") | |
$md = Get-Content (Join-Path $_.item 'readme.md') -Raw | |
$imageJson = @() | |
$_.images | | |
Foreach-Object { | |
$imagePath = $_ | |
$imageName = (Get-Item $_).Name | |
#新規投稿ページに遷移する | |
$chromeDriver.Url = "https://dev.to/new" | |
$webDriverWait.Until([OpenQA.Selenium.Support.UI.ExpectedConditions]::TitleContains("New Post")) | |
#IMAGEボタンクリック | |
$chromeDriver.FindElementByXPath('//*[@id="article-form"]/form/div[1]/button').Click() | |
$webDriverWait.Until([OpenQA.Selenium.Support.UI.ExpectedConditions]::ElementExists([OpenQA.Selenium.By]::ClassName("articleform__overlay"))) | |
#画像アップロード | |
$chromeDriver.FindElementByXPath('//*[@id="article-form"]/form/div[3]/div[1]/div[1]/input').SendKeys($imagePath) | |
$webDriverWait.Until([OpenQA.Selenium.Support.UI.ExpectedConditions]::ElementExists([OpenQA.Selenium.By]::Id("image-direct-copy-link-input"))) | |
#画像のURL取得 | |
$imageTextArea = $chromeDriver.FindElementById("image-direct-copy-link-input") | |
$imageLink = $imageTextArea.GetAttribute("value") | |
# 画像があるならアップロードしてファイル名とアップロードしたURLを対応付ける | |
# 画像があるならindex.mdのファイル名をアップロードしたURLに置換する | |
[System.Console]::WriteLine("$($imagePath) to $($imageLink)") | |
$imageJson += @{from = $imagePath; to = $imageLink } | |
$md = $md.Replace($imageName, $imageLink) | |
#Doneボタン | |
$chromeDriver.FindElementByXPath('//*[@id="article-form"]/form/div[3]/div[2]/button').Click() | |
$webDriverWait.Until([OpenQA.Selenium.Support.UI.ExpectedConditions]::ElementExists([OpenQA.Selenium.By]::XPath('//*[@id="article-form"]/form/div[1]/button'))) | |
Start-Sleep 10 | |
} | | |
Out-Null | |
if ($imageJson.Count -gt 0) { | |
$imageJson | ConvertTo-Json | Out-File (Join-Path $_.item 'image.json') | |
} | |
$tags = $meta.tags | Select-Object -ExpandProperty name | |
if ($tags.Count -gt 4) { | |
$tags = $tags | Where-Object { !($blackListTags.Contains($_)) } | |
} | |
$utcDate = [TimeZoneInfo]::ConvertTimeToUtc([DateTime]$meta.updated_at).ToString('yyyyMMddTHH:mmZ') | |
# meta.jsonからタイトル、タグ、更新日時、URLを取得 | |
$body = @" | |
--- | |
title: $($meta.title) | |
published: false | |
tags: $($tags -join ', ') | |
date: $($utcDate) | |
canonical_url: $($meta.url) | |
--- | |
$($md) | |
"@ | |
@{article = @{ | |
title = $meta.title; | |
published = $false; | |
body_markdown = $body; | |
tags = $tags; | |
canonical_url = $meta.url; | |
} | |
} | |
} | |
} | | |
Select-Object -ExpandProperty request | | |
ForEach-Object { | |
# dev.toのAPIをキックする | |
$headers = @{'api-key' = $devToApiKey } | |
$body = [Text.Encoding]::UTF8.GetBytes(($_ | ConvertTo-Json -Compress)) | |
$response = Invoke-RestMethod -Method Post -Uri https://dev.to/api/articles -ContentType application/json -Headers $headers -Body $body | |
[System.Console]::WriteLine("done $($response.url)") | |
Start-Sleep 5 | |
} | |
#chrome終了 | |
$chromeDriver.Quit() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$userId = 'your-user-name' | |
$imageFolder = "" # replace image path | |
$perPage = 100 | |
(Invoke-RestMethod -Uri "https://qiita.com/api/v2/users/${userId}").items_count | | |
Select-Object @{label = 'pages'; expression = { 1..([Math]::Truncate($_ / $perPage) + 1) } } | | |
Select-Object -ExpandProperty pages | | |
Select-Object @{ | |
label = 'item' | |
expression = { | |
Invoke-RestMethod -Uri "https://qiita.com/api/v2/users/${userId}/items?per_page=${perPage}&page=${_}" | | |
Select-Object -ExpandProperty SyncRoot | | |
Select-Object @{ label = 'images'; expression = { | |
([regex]"\((?<url>(?<parent>https://qiita-image-store\.s3\.[\w-.]*amazonaws.com/([\w-]+/)*?)(?<file>[\w-]+\.[\w]+?)?)\)").Matches($_.body) | | |
Select-Object @{ label = 'url'; expression = { $_.Groups["url"].Value } }, | |
@{ label = 'parent'; expression = { $_.Groups["parent"].Value } }, | |
@{ label = 'file'; expression = { $_.Groups["file"].Value } } | | |
Where-Object { -not [string]::IsNullOrEmpty($_.url) } | |
} | |
}, | |
id, url, title, tags, body, created_at, updated_at | |
} | |
} | | |
Select-Object -ExpandProperty item | | |
ForEach-Object -Begin { | |
$i = 0 | |
} -Process { | |
$i++ | |
$item_folder = Join-Path "items" $_.id | |
$md = Join-Path $item_folder "$($_.id).md" | |
$indexMd = Join-Path $item_folder "readme.md" | |
$metaJson = Join-Path $item_folder "meta.json" | |
$readmeMd = Join-Path "items" "readme.md" | |
$existsOutputFolder = Test-Path -PathType Container $item_folder | |
if (-not $existsOutputFolder) { | |
New-Item -ItemType Directory $item_folder | |
} | |
"1. [$($_.title)]($($_.id)/readme.md)" | Out-File $readmeMd -Append:($i -gt 1) | |
if ($existsOutputFolder) { | |
Return | |
} | |
$c = ([DateTime]$_.created_at) | |
$u = ([DateTime]$_.updated_at) | |
Write-Host ("{0:yyyy-MM-dd HH-mm-ss}, {1:yyyy-MM-dd HH-mm-ss}, {2}.md, {3}, {4}" -f $c, $u, $_.id, $_.title, ($_.tags | Select-Object -ExpandProperty name | ConvertTo-Json -Compress)) | |
$_ | Select-Object id, title, tags, url, created_at, updated_at | ConvertTo-Json | Out-File $metaJson | |
$_.body | Out-File $md -NoNewline | |
$indexBody = $_.body | |
$_.images | | |
ForEach-Object { | |
$indexBody = $indexBody.Replace($_.parent, $imageFolder) | |
} | |
$indexBody | Out-File $indexMd -NoNewline | |
$_.images | ForEach-Object { | |
Write-Host "`t$($_.url)" | |
Invoke-WebRequest -Uri $_.url -OutFile (Join-Path $item_folder $_.file) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$userId = 'your-user-name' | |
$pages = 1 # your-stock-pages | |
$imageFolder = "" # replace image path | |
$perPage = 100 | |
($pages * 20) | | |
Select-Object @{label = 'pages'; expression = { 1..([Math]::Truncate($_ / $perPage) + 1) } } | | |
Select-Object -ExpandProperty pages | | |
Select-Object @{ | |
label = 'item' | |
expression = { | |
Invoke-RestMethod -Uri "https://qiita.com/api/v2/users/${userId}/stocks?per_page=${perPage}&page=${_}" | | |
Select-Object -ExpandProperty SyncRoot | | |
Select-Object @{ label = 'images'; expression = { | |
([regex]"\((?<url>(?<parent>https://qiita-image-store\.s3\.[\w-.]*amazonaws.com/([\w-]+/)*?)(?<file>[\w-]+\.[\w]+?)?)\)").Matches($_.body) | | |
Select-Object @{ label = 'url'; expression = { $_.Groups["url"].Value } }, | |
@{ label = 'parent'; expression = { $_.Groups["parent"].Value } }, | |
@{ label = 'file'; expression = { $_.Groups["file"].Value } } | | |
Where-Object { -not [string]::IsNullOrEmpty($_.url) } | |
} | |
}, | |
id, user, url, title, tags, body | |
} | |
} | | |
Select-Object -ExpandProperty item | | |
ForEach-Object -Begin { | |
$i = 0 | |
} -Process { | |
$i++ | |
$item_folder = Join-Path "stock" $_.id | |
$md = Join-Path $item_folder "$($_.id).md" | |
$indexMd = Join-Path $item_folder "readme.md" | |
$metaJson = Join-Path $item_folder "meta.json" | |
$readmeMd = Join-Path "stock" "readme.md" | |
$existsOutputFolder = Test-Path -PathType Container $item_folder | |
if (-not $existsOutputFolder) { | |
New-Item -ItemType Directory $item_folder | |
} | |
"1. [$($_.title)]($($_.id)/readme.md)" | Out-File $readmeMd -Append:($i -gt 1) | |
if ($existsOutputFolder) { | |
Return | |
} | |
Write-Host ("{0}.md, {1}, {2}" -f $_.id, $_.title, ($_.tags | Select-Object -ExpandProperty name | ConvertTo-Json -Compress)) | |
$_ | Select-Object id, user, title, tags, url | ConvertTo-Json | Out-File $metaJson | |
$_.body | Out-File $md -NoNewline | |
$indexBody = $_.body | |
$_.images | | |
ForEach-Object { | |
$indexBody = $indexBody.Replace($_.parent, $imageFolder) | |
} | |
$indexBody | Out-File $indexMd -NoNewline | |
$_.images | ForEach-Object { | |
Write-Host "`t$($_.url)" | |
Invoke-WebRequest -Uri $_.url -OutFile (Join-Path $item_folder $_.file) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment