Commit d42bb8ec authored by 汪洋's avatar 汪洋

优化了一部分代码逻辑;优化了Log的形式

parent de92dc3f
......@@ -7,9 +7,9 @@
objects = {
/* Begin PBXBuildFile section */
D30D4AF0224CC3FF004CE936 /* Jira.swift in Sources */ = {isa = PBXBuildFile; fileRef = D30D4AEF224CC3FF004CE936 /* Jira.swift */; };
D30D4AF2224CCDE0004CE936 /* File in Resources */ = {isa = PBXBuildFile; fileRef = D30D4AF1224CCDE0004CE936 /* File */; };
D35CADA92642EF611E6ABE62 /* Pods_AutoJira.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D013D83D9CA164C1F113E5D /* Pods_AutoJira.framework */; };
D386B4C82250A9AB003435E9 /* JiraProject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D386B4C72250A9AB003435E9 /* JiraProject.swift */; };
D3E595DF22240DCC004DCC62 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3E595DE22240DCC004DCC62 /* AppDelegate.swift */; };
D3E595E122240DCC004DCC62 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3E595E022240DCC004DCC62 /* ViewController.swift */; };
D3E595E322240DCF004DCC62 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D3E595E222240DCF004DCC62 /* Assets.xcassets */; };
......@@ -22,7 +22,7 @@
D3E596012227B5A2004DCC62 /* XPath备忘.md in Resources */ = {isa = PBXBuildFile; fileRef = D3E596002227B5A2004DCC62 /* XPath备忘.md */; };
D3E596032227B5CD004DCC62 /* 创建story.md in Resources */ = {isa = PBXBuildFile; fileRef = D3E596022227B5CD004DCC62 /* 创建story.md */; };
D3E596052227B628004DCC62 /* 关联story.md in Resources */ = {isa = PBXBuildFile; fileRef = D3E596042227B628004DCC62 /* 关联story.md */; };
D3E596092227B6F9004DCC62 /* RepeatdWork.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3E596082227B6F9004DCC62 /* RepeatdWork.swift */; };
D3E596092227B6F9004DCC62 /* JiraAutomator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3E596082227B6F9004DCC62 /* JiraAutomator.swift */; };
D3E5960B222E1E60004DCC62 /* 登录Login.md in Resources */ = {isa = PBXBuildFile; fileRef = D3E5960A222E1E60004DCC62 /* 登录Login.md */; };
D3E5960D222E2D1D004DCC62 /* Login.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3E5960C222E2D1D004DCC62 /* Login.swift */; };
D3E5960F222FBDBC004DCC62 /* 获取EditIssue.md in Resources */ = {isa = PBXBuildFile; fileRef = D3E5960E222FBDBB004DCC62 /* 获取EditIssue.md */; };
......@@ -35,8 +35,8 @@
6D013D83D9CA164C1F113E5D /* Pods_AutoJira.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AutoJira.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8D92517B7E535BFBB153A49B /* Pods-AutoJira.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AutoJira.release.xcconfig"; path = "Target Support Files/Pods-AutoJira/Pods-AutoJira.release.xcconfig"; sourceTree = "<group>"; };
ACBE7590179B597A40CC91EE /* Pods-AutoJira.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AutoJira.debug.xcconfig"; path = "Target Support Files/Pods-AutoJira/Pods-AutoJira.debug.xcconfig"; sourceTree = "<group>"; };
D30D4AEF224CC3FF004CE936 /* Jira.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Jira.swift; sourceTree = "<group>"; };
D30D4AF1224CCDE0004CE936 /* File */ = {isa = PBXFileReference; lastKnownFileType = text; path = File; sourceTree = "<group>"; };
D386B4C72250A9AB003435E9 /* JiraProject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JiraProject.swift; sourceTree = "<group>"; };
D3E595DB22240DCC004DCC62 /* AutoJira.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AutoJira.app; sourceTree = BUILT_PRODUCTS_DIR; };
D3E595DE22240DCC004DCC62 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
D3E595E022240DCC004DCC62 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
......@@ -52,7 +52,7 @@
D3E596002227B5A2004DCC62 /* XPath备忘.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "XPath备忘.md"; sourceTree = "<group>"; };
D3E596022227B5CD004DCC62 /* 创建story.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "创建story.md"; sourceTree = "<group>"; };
D3E596042227B628004DCC62 /* 关联story.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "关联story.md"; sourceTree = "<group>"; };
D3E596082227B6F9004DCC62 /* RepeatdWork.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RepeatdWork.swift; sourceTree = "<group>"; };
D3E596082227B6F9004DCC62 /* JiraAutomator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JiraAutomator.swift; sourceTree = "<group>"; };
D3E5960A222E1E60004DCC62 /* 登录Login.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "登录Login.md"; sourceTree = "<group>"; };
D3E5960C222E2D1D004DCC62 /* Login.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Login.swift; sourceTree = "<group>"; };
D3E5960E222FBDBB004DCC62 /* 获取EditIssue.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "获取EditIssue.md"; sourceTree = "<group>"; };
......@@ -105,12 +105,12 @@
D3E595FB2227B559004DCC62 /* 代码阅读 */,
D3E595DE22240DCC004DCC62 /* AppDelegate.swift */,
D3E595E022240DCC004DCC62 /* ViewController.swift */,
D3E596082227B6F9004DCC62 /* RepeatdWork.swift */,
D3E596082227B6F9004DCC62 /* JiraAutomator.swift */,
D3E595EE22252765004DCC62 /* Page.swift */,
D3E595F42226AEC7004DCC62 /* Story.swift */,
D3E595F22226AE50004DCC62 /* RequestUtils.swift */,
D30D4AEF224CC3FF004CE936 /* Jira.swift */,
D386B4C72250A9AB003435E9 /* JiraProject.swift */,
D3E5960C222E2D1D004DCC62 /* Login.swift */,
D3E595F22226AE50004DCC62 /* RequestUtils.swift */,
D3E595E222240DCF004DCC62 /* Assets.xcassets */,
D3E595E422240DCF004DCC62 /* Main.storyboard */,
D3E595E722240DCF004DCC62 /* Info.plist */,
......@@ -283,9 +283,9 @@
buildActionMask = 2147483647;
files = (
D3E5960D222E2D1D004DCC62 /* Login.swift in Sources */,
D3E596092227B6F9004DCC62 /* RepeatdWork.swift in Sources */,
D3E596092227B6F9004DCC62 /* JiraAutomator.swift in Sources */,
D3E595E122240DCC004DCC62 /* ViewController.swift in Sources */,
D30D4AF0224CC3FF004CE936 /* Jira.swift in Sources */,
D386B4C82250A9AB003435E9 /* JiraProject.swift in Sources */,
D3E595F52226AEC7004DCC62 /* Story.swift in Sources */,
D3E595DF22240DCC004DCC62 /* AppDelegate.swift in Sources */,
D3E595EF22252765004DCC62 /* Page.swift in Sources */,
......
......@@ -2,22 +2,4 @@
<Bucket
type = "0"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "AutoJira/Page.swift"
timestampString = "575300302.606153"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "89"
endingLineNumber = "89"
landmarkName = "getUser(tr:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>
......@@ -785,7 +785,7 @@
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="pLx-ea-hpy">
<rect key="frame" x="106" y="326" width="540" height="22"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" title="http://wiki.wanmeizhensuo.com/pages/viewpage.action?pageId=18581629" drawsBackground="YES" id="xMA-0w-54b">
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" title="http://wiki.wanmeizhensuo.com/pages/viewpage.action?pageId=18587956" drawsBackground="YES" id="xMA-0w-54b">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
......@@ -817,7 +817,7 @@
</menu>
</popUpButtonCell>
<connections>
<action selector="versionSelectionAction:" target="XfG-lQ-9wD" id="mnQ-V7-Ndt"/>
<action selector="sprintSelectionAction:" target="XfG-lQ-9wD" id="3IP-CD-xOq"/>
</connections>
</popUpButton>
</subviews>
......@@ -845,8 +845,8 @@
<connections>
<outlet property="logTextView" destination="oWH-27-6AA" id="HNL-mY-PU6"/>
<outlet property="segment" destination="Odk-md-Lt7" id="rC3-jS-ysv"/>
<outlet property="sprintPopup" destination="Ajo-Dg-gTt" id="6sw-cz-Cld"/>
<outlet property="urlTextField" destination="pLx-ea-hpy" id="5IN-61-bR6"/>
<outlet property="versionPopup" destination="Ajo-Dg-gTt" id="Nus-dW-6QJ"/>
</connections>
</viewController>
<customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
......
//
// Jira.swift
// AutoJira
//
// Created by wangyang on 2019/3/28.
// Copyright © 2019 wangyang. All rights reserved.
//
import Cocoa
class Jira: NSObject {
var jiraProjectId: String = ""
var sprints: [Sprint] = []
var currentSprint: Sprint?
var subtask_id: String = ""
convenience init(jiraProjectId: String, sprints: [Sprint]) {
self.init()
self.jiraProjectId = jiraProjectId
self.sprints = sprints
// like sub task 10302
// gengmei sub task 10003
if jiraProjectId == "10108" {
// 更美
subtask_id = "10003"
} else {
// like
subtask_id = "10302"
}
}
}
......@@ -8,20 +8,66 @@
import Foundation
import Kanna
import ReactiveCocoa
struct RepeatedWork {
static var jira: Jira?
class JiraAutomator: NSObject {
static let shared = JiraAutomator()
var jira: JiraProject?
var currentSprint: Sprint?
let projects = [JiraProjectType.gengmei: JiraProject(projectType: .gengmei),
JiraProjectType.like: JiraProject(projectType: .like)]
// 参考"获取迭代列表.md"
func fetchJiraSprints() {
let url = URL(string: "http://jira.wanmeizhensuo.com/rest/greenhopper/1.0/sprint/picker?query=&_=1552128647090")!
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.sync { [weak self] (data, response, error) in
if data == nil {
Log.append(error)
return
}
if self == nil {
Log.append(error: "fetchSprintList self 为空")
return
}
if let json = (try? JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments)) as? [String: Any] {
guard let sprints = json["suggestions"] as? [[String: Any]] else {
Log.append(error: "json中没有suggestions")
return
}
for sprintDic in sprints {
if let boardName = sprintDic["boardName"] as? String {
if boardName == "Alpha" {
let sprint = Sprint(dic: sprintDic)
self!.projects[JiraProjectType.like]!.sprints.append(sprint)
} else if boardName == "USER board" {
let sprint = Sprint(dic: sprintDic)
self!.projects[JiraProjectType.gengmei]!.sprints.append(sprint)
}
}
}
} else {
Log.append(error: "获取迭代列表失败:\n\(response.debugDescription)")
}
}
}
func switchProject(type: JiraProjectType) {
self.jira = projects[type]
}
// url是“开发与测试资源安排”中的迭代文件
static func fuckit(on sprintUrl: String) {
func start(on sprintUrl: String) {
let url = URL(string: sprintUrl)!
var request = URLRequest(url: url)
request.httpMethod = "GET"
URLSession.shared.dataTask(with: request) { (data, response, error) in
URLSession.shared.dataTask(with: request) { [weak self] (data, response, error) in
DispatchQueue.main.async {
if data != nil {
doTheRepeatedWork(data!)
self?.doTheRepeatedWork(data!)
} else {
Log.append(error)
}
......@@ -29,8 +75,7 @@ struct RepeatedWork {
}.resume()
}
static func doTheRepeatedWork(_ data: Data) {
Log.append("开始重复工作")
func doTheRepeatedWork(_ data: Data) {
guard let html = String(data: data, encoding: .utf8) else {
return
}
......@@ -43,32 +88,42 @@ struct RepeatedWork {
//
let obj = doc.xpath("//*[@id=\"main-content\"]/div[2]/table/tbody//td[@data-content-id]")
if obj.count == 0 {
Log.append("没有需要列表\nhtml")
Log.append(error: "根据XPath没有找到需求。一般来说是XPath出错,原始html内容为\(html)")
return
}
// 此处的每一个node就是一个需求,可以使用node.toHTML来查看其内容
var index = 1
Log.append("一共\(obj.count)个需求")
for node in obj.makeIterator() {
let page = Page(page: node)
Log.append("开始处理第\(index)个")
let page = Page(page: node)
if !page.isValide() {
Log.append("\(node.toHTML!) page 信息有问题")
Log.append(error: "\(page.title): 验证未通过")
continue
}
if let story = Story.createStory(with: page.title, jiraProjectId: RepeatedWork.jira!.jiraProjectId) {
page.story = story
} else {
Log.append("\(node.toHTML!) story创建出错")
if page.hasCreateStory() {
Log.append("\(page.title): 已经创建story,跳过其它步骤")
continue
}
page.story.connect(to: page.pageId, with: page.lastFetchTime)
if let foId = page.fo?.id {
page.story.editStoryInfo(assignee: foId)
if let story = Story.createStory(with: page.title) {
page.story = story
} else {
Log.append("\(node.toHTML!) 没有正确修改story")
Log.append(error: "\(page.title): story创建出错")
continue
}
page.story.createSubtask(page: page)
Log.append("story创建完成")
page.story.connect(to: page.pageId, with: page.lastFetchTime)
// if let foId = page.fo?.id {
// page.story.editStoryInfo(assignee: foId)
// } else {
// Log.append(error: "\(node.toHTML!) 没有正确修改story")
// }
// page.story.createSubtask(page: page)
index += 1
}
}
}
//
// Jira.swift
// AutoJira
//
// Created by wangyang on 2019/3/28.
// Copyright © 2019 wangyang. All rights reserved.
//
import Cocoa
class JiraProject: NSObject {
var id: String = ""
var sprints: [Sprint] = []
var subtask_id: String = ""
convenience init(projectType: JiraProjectType) {
self.init()
self.id = projectType.rawValue
self.subtask_id = projectType.subtaskId()
}
}
enum JiraProjectType: String {
case like = "10500"
case gengmei = "10108"
func subtaskId() -> String {
switch self {
case .like:
return "10302"
case .gengmei:
return "10003"
}
}
}
enum SprintState: String {
case future = "FUTURE"
case active = "ACTIVE"
case none = ""
}
struct Sprint {
let name: String
let id: Int
let stateKey: SprintState
init(dic: [String: Any]) {
if let name = dic["name"] as? String,
let id = dic["id"] as? Int,
let stateKey = dic["stateKey"] as? String,
let s = SprintState(rawValue: stateKey) {
self.name = name
self.id = id
self.stateKey = s
} else {
name = ""
id = 0
stateKey = .none
}
}
}
......@@ -14,6 +14,7 @@ struct People {
var name: String
var id: String
}
/*
可以使用html属性进一步来查看当前所代码的html代码。
*/
......@@ -45,24 +46,24 @@ class Page: NSObject {
// 核心是得到developers,其它都是错误处理
guard let tableTr = html?.xpath("//*[@id=\"main-content\"]/div[1]/div/table/tbody/tr") else {
Log.append("没有得到需求文档的table")
Log.append(error: "没有得到需求文档的table")
return
}
// 循环table中的每一行,如果该行是FO或者开发这一类的,就进行人员解析
for tr in tableTr.makeIterator() {
guard let th = tr.at_xpath("th")?.innerHTML else {
Log.append("\(tr.toHTML!) table tr/th中没有span")
Log.append(error: "\(tr.toHTML!) table tr/th中没有span")
continue
}
if th.contains("FO") {
if let user = getUser(tr: tr).first {
fo = user
} else {
Log.append("\(tr.toHTML!) FO 没有正确生成")
Log.append(error: "\(tr.toHTML!) FO 没有正确生成")
continue
}
} else if th.contains("测试") || th.contains("开发") || th.contains("数据") {
} else if th.contains("测试") || th.contains("开发") || th.contains("数据") || th.contains("策略"){
developers.append(contentsOf: getUser(tr: tr))
}
}
......@@ -79,11 +80,7 @@ class Page: NSObject {
users.append(People(name: name, id: name_id))
} else {
if html.toHTML != nil {
Log.append("\(html.toHTML!) 没有成功解析")
continue
}
Log.append("\(html)没有成功解析")
Log.append(error: "\(title): getUser没有成功解析")
}
}
return users
......@@ -91,14 +88,21 @@ class Page: NSObject {
func isValide() -> Bool {
if html == nil {
Log.append("\(pageUrl) 未正常解析")
Log.append(error: "\(pageUrl) 未正常解析")
return false
}
Log.append("创建Page成功: \(title)")
if html!.body!.toHTML!.contains("是/否") {
Log.append(error: "\(title) 文档中包含“是/否”")
return false
}
return true
}
func hasCreateStory() -> Bool {
return html!.body!.toHTML!.contains("jira-issue-key")
}
// 下载需求页面,从中得到必要的信息
func loadHTML() -> HTMLDocument? {
let url = URL(string: pageUrl)!
......
......@@ -28,14 +28,13 @@ class Story: NSObject {
///
/// - Parameter page: Page实例
/// - Returns: storyKey
static func createStory(with title: String, jiraProjectId: String) -> Story? {
Log.append("创建story")
static func createStory(with title: String) -> Story? {
let url = URL(string: "http://wiki.wanmeizhensuo.com/rest/jira-integration/1.0/issues?applicationId=54ed5447-b029-3ef0-b638-681b4647313b")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let jsonDic = ["issues": [["fields":["project":["id":RepeatedWork.jira!.jiraProjectId],"issuetype":["id":"10001"],"summary": title]]]]
let jsonDic = ["issues": [["fields":["project":["id":JiraAutomator.shared.jira!.id],"issuetype":["id":"10001"],"summary": title]]]]
request.httpBody = try? JSONSerialization.data(withJSONObject: jsonDic, options: [])
var story: Story?
request.sync { (data, response, error) in
......@@ -53,7 +52,7 @@ class Story: NSObject {
story?.summary = title
Log.append("创建story请求成功:\(story!.storyKey)")
} else {
Log.append("创建story请求失败:\n\(response.debugDescription)")
Log.append(error: "创建story请求失败:\n\(response.debugDescription)")
}
}
return story
......@@ -61,7 +60,6 @@ class Story: NSObject {
/// 关联文档与story
func connect(to pageId: String, with pageLastFetchTime: String) {
Log.append("关联story与wiki")
let url = URL(string: "http://wiki.wanmeizhensuo.com/rest/highlighting/1.0/insert-storage-fragment")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
......@@ -79,11 +77,11 @@ class Story: NSObject {
if json {
Log.append("关联story与wiki成功")
} else {
Log.append("关联story与wiki失败,很有可能是文档中没有\"项目背景\"四个字。response:\n \(response.debugDescription)")
Log.append(error: "关联story与wiki失败,很有可能是文档中没有\"项目背景\"四个字。response:\n \(response.debugDescription)")
}
return
} else {
Log.append("关联story与wiki失败,json没有正常解析。response:\n \(response.debugDescription)")
Log.append(error: "关联story与wiki失败,json没有正常解析。response:\n \(response.debugDescription)")
}
}
}
......@@ -91,14 +89,13 @@ class Story: NSObject {
/// 修改story的“指派人”
/// 修改story所在的sprint
func editStoryInfo(assignee: String) {
Log.append("编辑story的assign与sprint")
let url = URL(string: "http://jira.wanmeizhensuo.com/secure/QuickEditIssue.jspa?issueId=\(storyId)&decorator=none")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
guard let formString = getEditIssueFormdata(assignee: assignee) else {
Log.append("editStoryInfo 失败")
Log.append(error: "editStoryInfo 失败")
return
}
......@@ -128,21 +125,21 @@ class Story: NSObject {
}
if json == nil {
Log.append("secure/QuickEditIssue出错")
Log.append(error: "secure/QuickEditIssue出错")
return nil
}
guard let formToken = json!["formToken"] as? String else {
Log.append("formToken出错")
Log.append(error: "formToken出错")
return nil
}
guard let atl_token = json!["atl_token"] as? String else {
Log.append("atl_token出错")
Log.append(error: "atl_token出错")
return nil
}
let formData = "id=\(storyId)&atl_token=\(atl_token)&formToken=\(formToken)&assignee=\(assignee)&customfield_10005=\(RepeatedWork.jira!.currentSprint!.id)&isCreateIssue=false&isEditIssue=true&summary=\(summary)&issuetype=10001&reporter=wangyang&description=开始时间%2B开发人员%2B任务名称%2B预计开发时间"
let formData = "id=\(storyId)&atl_token=\(atl_token)&formToken=\(formToken)&assignee=\(assignee)&customfield_10005=\(JiraAutomator.shared.currentSprint!.id)&isCreateIssue=false&isEditIssue=true&summary=\(summary)&issuetype=10001&reporter=wangyang&description=开始时间%2B开发人员%2B任务名称%2B预计开发时间"
return formData
}
......@@ -171,7 +168,7 @@ class Story: NSObject {
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let formString = "pid=\(pid)&issuetype=\(RepeatedWork.jira!.subtask_id)&parentIssueId=\(storyId)&atl_token=\(subtask_atl_token)&formToken=\(subtask_formToken)&summary=\(summary)&isCreateIssue=true&assignee=\(assignee)&reporter=wangyang&priority=3&issuelinks=issuelinks&issuelinks-linktype=blocks&isCreateIssue=true&isEditIssue=false&"
let formString = "pid=\(pid)&issuetype=\(JiraAutomator.shared.jira!.subtask_id)&parentIssueId=\(storyId)&atl_token=\(subtask_atl_token)&formToken=\(subtask_formToken)&summary=\(summary)&isCreateIssue=true&assignee=\(assignee)&reporter=wangyang&priority=3&issuelinks=issuelinks&issuelinks-linktype=blocks&isCreateIssue=true&isEditIssue=false&"
let formData = formString.data(using: .utf8)
request.httpBody = formData
......@@ -199,36 +196,36 @@ class Story: NSObject {
}
if json == nil {
Log.append("secure/QuickEditIssue出错")
Log.append(error: "secure/QuickEditIssue出错")
return
}
guard let formToken = json!["formToken"] as? String else {
Log.append("formToken出错")
Log.append(error: "formToken出错")
return
}
self.subtask_formToken = formToken
guard let atl_token = json!["atl_token"] as? String else {
Log.append("atl_token出错")
Log.append(error: "atl_token出错")
return
}
self.subtask_atl_token = atl_token
guard let fields = json!["fields"] as? [[String: Any]] else {
Log.append("fields出错")
Log.append(error: "fields出错")
return
}
if fields.count == 0 {
Log.append("fields.count == 0 出错")
Log.append(error: "fields.count == 0 出错")
return
}
let firstField = fields[0]
let editHtml = firstField["editHtml"] as! String
guard let projectHtml = try? HTML(html: editHtml, encoding: .utf8) else {
Log.append("projectHtml出错")
Log.append(error: "projectHtml出错")
return
}
......
......@@ -9,130 +9,71 @@
import Cocoa
import Kanna
enum SprintState: String {
case future = "FUTURE"
case active = "ACTIVE"
case none = ""
}
struct Sprint {
let name: String
let id: Int
let stateKey: SprintState
init(dic: [String: Any]) {
if let name = dic["name"] as? String,
let id = dic["id"] as? Int,
let stateKey = dic["stateKey"] as? String,
let s = SprintState(rawValue: stateKey) {
self.name = name
self.id = id
self.stateKey = s
} else {
name = ""
id = 0
stateKey = .none
}
}
}
class ViewController: NSViewController {
@IBOutlet var logTextView: NSTextView!
@IBOutlet weak var urlTextField: NSTextField!
@IBOutlet weak var versionPopup: NSPopUpButton!
@IBOutlet weak var sprintPopup: NSPopUpButton!
@IBOutlet weak var segment: NSSegmentedControl!
var jiraProjects: [Int: Jira] = [:]
override func viewDidLoad() {
super.viewDidLoad()
Login.loginWiki()
Login.loginJira()
fetchJiraProjects()
JiraAutomator.shared.fetchJiraSprints()
segment.selectedSegment = 0
switchProject(segment)
}
// 参考"获取迭代列表.md"
func fetchJiraProjects() {
var gengmeiSprints: [Sprint] = []
var likeSprints: [Sprint] = []
let url = URL(string: "http://jira.wanmeizhensuo.com/rest/greenhopper/1.0/sprint/picker?query=&_=1552128647090")!
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.sync { [weak self] (data, response, error) in
if data == nil {
Log.append(error)
return
}
if self == nil {
Log.append("fetchSprintList self 为空")
return
}
if let json = (try? JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments)) as? [String: Any] {
guard let sprints = json["suggestions"] as? [[String: Any]] else {
Log.append("json中没有suggestions")
return
}
for sprintDic in sprints {
if let boardName = sprintDic["boardName"] as? String {
if boardName == "Alpha" {
let sprint = Sprint(dic: sprintDic)
likeSprints.append(sprint)
} else if boardName == "USER board" {
let sprint = Sprint(dic: sprintDic)
gengmeiSprints.append(sprint)
}
}
}
} else {
Log.append("获取迭代列表失败:\n\(response.debugDescription)")
}
}
// project AL: 10500
// project USER: 10108
jiraProjects = [0: Jira(jiraProjectId: "10108", sprints: gengmeiSprints),
1: Jira(jiraProjectId: "10500", sprints: likeSprints)]
}
@IBAction func switchProject(_ sender: NSSegmentedControl) {
versionPopup.removeAllItems()
versionPopup.addItem(withTitle: "未选择版本号")
RepeatedWork.jira = jiraProjects[sender.indexOfSelectedItem]!
versionPopup.addItems(withTitles: RepeatedWork.jira!.sprints.map { return $0.name })
sprintPopup.removeAllItems()
sprintPopup.addItem(withTitle: "未选择版本号")
if sender.indexOfSelectedItem == 0 {
JiraAutomator.shared.switchProject(type: .gengmei)
} else {
JiraAutomator.shared.switchProject(type: .like)
}
sprintPopup.addItems(withTitles: JiraAutomator.shared.jira!.sprints.map { return $0.name })
}
@IBAction func versionSelectionAction(_ sender: NSPopUpButton) {
@IBAction func sprintSelectionAction(_ sender: NSPopUpButton) {
if sender.indexOfSelectedItem > 0 {
RepeatedWork.jira?.currentSprint = RepeatedWork.jira!.sprints[sender.indexOfSelectedItem - 1]
JiraAutomator.shared.currentSprint? = JiraAutomator.shared.jira!.sprints[sender.indexOfSelectedItem - 1]
} else {
RepeatedWork.jira = nil
JiraAutomator.shared.currentSprint = nil
}
}
@IBAction func OKAction(_ sender: Any) {
if RepeatedWork.jira == nil {
Log.append("先选择版本号")
if sprintPopup.indexOfSelectedItem == 0 {
Log.append(error: "先选择版本号")
return
}
if urlTextField.stringValue.count == 0 ||
urlTextField.stringValue.count == 0 {
Log.append("需求列表地址没有填写")
if urlTextField.stringValue.count == 0 {
Log.append(error: "填写需求列表地址")
return
}
RepeatedWork.fuckit(on: urlTextField.stringValue)
JiraAutomator.shared.start(on: urlTextField.stringValue)
}
}
class Log: NSObject {
static func append(error logText: String) {
DispatchQueue.main.async {
if let controller = NSApplication.shared.keyWindow?.contentViewController as? ViewController {
let textStorage = controller.logTextView.textStorage!
let log = NSMutableAttributedString(string: "\n" + logText, attributes: [NSAttributedString.Key.foregroundColor : NSColor.red])
textStorage.append(log)
}
}
}
static func append(_ logText: String) {
DispatchQueue.main.async {
if let controller = NSApplication.shared.keyWindow?.contentViewController as? ViewController {
let textStorage = controller.logTextView.textStorage!
textStorage.append(NSAttributedString(string: "\n"))
textStorage.append(NSAttributedString(string: logText))
let log = NSMutableAttributedString(string: "\n" + logText, attributes: [NSAttributedString.Key.foregroundColor : NSColor.black])
textStorage.append(log)
}
}
}
......@@ -140,7 +81,7 @@ class Log: NSObject {
static func append(_ error: Error?) {
DispatchQueue.main.async {
if let err = error as NSError? {
append(err.localizedDescription)
append(error: err.localizedDescription)
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment