- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Re: Re: Trac -> Jira
Thu, 2011-05-19, 17:34
Get the Jira component created, and we could discuss it there :)
On 19 May 2011 17:30, Chris Marshall <oxbow_lakes@hotmail.com> wrote:
--
Kevin Wright
gtalk / msn : kev.lee.wright@gmail.comkev.lee.wright@gmail.commail: kevin.wright@scalatechnology.com
vibe / skype: kev.lee.wrightquora: http://www.quora.com/Kevin-Wright
twitter: @thecoda
"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra
On 19 May 2011 17:30, Chris Marshall <oxbow_lakes@hotmail.com> wrote:
Indeed - would be good to split out the Standard Library into sub-components as well (e.g. collections, control, actors, parallel, parsing, swing, misc)
Date: Thu, 19 May 2011 17:23:51 +0100
Subject: Re: [scala-internals] Re: Trac -> Jira
From: kev.lee.wright@gmail.com
To: scala-internals@googlegroups.com
CC: johannes.rudolph@googlemail.com; lukas.rytz@epfl.ch
While on the subject, it makes sense if issues were assigned by default to the owner of the affected component. Groups could also be created to act as the owners here, if that helps.
On 19 May 2011 17:15, martin odersky <martin.odersky@epfl.ch> wrote:One thing that would be good to have is filter the list of possible assignees to Scala committers. It's quite hard to go through the list of everyone who's registered when you want top assign a ticket to someone.
Cheers
-- Martin
On Thu, May 19, 2011 at 10:28 AM, Fabien Salvi <fabien.salvi@epfl.ch> wrote:
Well, the problem is in scaladoc itself (eg link <https://lampsvn.epfl.ch/trac/scala/browser/scala/tags/R_2_9_0_final/src//library/scala/Function.scala#L1>)
The // wasn't a problem with Trac, but fisheye doesn't like it.
For the moment, I enabled again the browse source on the old URL and removed the redirection.
I will try to find a better solution.
On 05/18/2011 08:21 PM, Johannes Rudolph wrote:
Can we please get forwarders on https as well as http
And for source code as well, please. All the source links in Scaladoc
are right now broken even with http because there's a double slash
somewhere in the path.
--
Fabien Salvi
--
----------------------------------------------
Martin Odersky
Prof., EPFL and CEO, Typesafe
PSED, 1015 Lausanne, Switzerland
Tel. EPFL: +41 21 693 6863
Tel. Typesafe: +41 21 691 4967
--
Kevin Wright
gtalk / msn : kev.lee.wright@gmail.comkev.lee.wright@gmail.commail: kevin.wright@scalatechnology.com
vibe / skype: kev.lee.wrightquora: http://www.quora.com/Kevin-Wright
twitter: @thecoda
"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra
--
Kevin Wright
gtalk / msn : kev.lee.wright@gmail.comkev.lee.wright@gmail.commail: kevin.wright@scalatechnology.com
vibe / skype: kev.lee.wrightquora: http://www.quora.com/Kevin-Wright
twitter: @thecoda
"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra
Mon, 2011-05-23, 16:07
#2
Re: Re: Trac -> Jira
On 5/23/11 5:39 AM, Lukas Rytz wrote:
> So we probably have to do it with either
> - A
> Plugin http://confluence.atlassian.com/display/JIRA043/JIRA+Development+Hub
> - The SOAP
> API http://confluence.atlassian.com/display/JIRA/Creating+a+SOAP+Client
> - The REST API http://docs.atlassian.com/jira/REST/latest/
I looked at the rest api, and couldn't even figure out if there's a way
to close a ticket. Not going to write a jira plugin or look at soap.
If someone can tell me what is the URL to close a given ticket number
and how you supply a closing comment with it, I can write a git
post-commit hook to parse the commit messages and close.
Mon, 2011-05-23, 16:17
#3
Re: Re: Trac -> Jira
On Mon, May 23, 2011 at 08:03:30AM -0700, Paul Phillips said
> On 5/23/11 5:39 AM, Lukas Rytz wrote:
> I looked at the rest api, and couldn't even figure out if there's a way
> to close a ticket. Not going to write a jira plugin or look at soap.
> If someone can tell me what is the URL to close a given ticket number
> and how you supply a closing comment with it, I can write a git
> post-commit hook to parse the commit messages and close.
Looks like this is the REST call to change a ticket's state
http://docs.atlassian.com/jira/REST/latest/#id35825437
though you have to figure out what is the right transition ID.
Tue, 2011-05-24, 08:57
#4
Re: Re: Trac -> Jira
GET this https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-1372/transitions (as a starting point)
obviously, you need to POST, and somehow auth first -- I guess this would be an excellent opportunity for you json mavens to put together a nice Scala script
cheersadriaan
On Mon, May 23, 2011 at 5:03 PM, Paul Phillips <paulp@improving.org> wrote:
obviously, you need to POST, and somehow auth first -- I guess this would be an excellent opportunity for you json mavens to put together a nice Scala script
cheersadriaan
On Mon, May 23, 2011 at 5:03 PM, Paul Phillips <paulp@improving.org> wrote:
On 5/23/11 5:39 AM, Lukas Rytz wrote:
> So we probably have to do it with either
> - A
> Plugin http://confluence.atlassian.com/display/JIRA043/JIRA+Development+Hub
> - The SOAP
> API http://confluence.atlassian.com/display/JIRA/Creating+a+SOAP+Client
> - The REST API http://docs.atlassian.com/jira/REST/latest/
I looked at the rest api, and couldn't even figure out if there's a way
to close a ticket. Not going to write a jira plugin or look at soap.
If someone can tell me what is the URL to close a given ticket number
and how you supply a closing comment with it, I can write a git
post-commit hook to parse the commit messages and close.
Tue, 2011-05-24, 10:57
#5
Re: Re: Trac -> Jira
I couldn't resist cobbling together an abomination of my ownobvious improvements would be to use lift-json, implement decent authentication,...
but it works and I had fun :-)
// cobbled together using the internets (mostly stackoverflow)// http://stackoverflow.com/questions/5564074/scala-http-operations/5571782#5571782 // http://stackoverflow.com/questions/4883100/how-to-handle-http-authentication-using-httpurlconnection/4883890#4883890 // JIRA's REST docs: http://docs.atlassian.com/jira/REST/latest/ (note that I couldn't figure out how to login by posting application/json -- using crude https basic auth)
import java.io.{OutputStreamWriter, BufferedReader, InputStreamReader}import java.net.{URLConnection, HttpURLConnection, URL}import scala.collection.JavaConversions._import scala.io.Source import java.net.URLEncoder.encode
val username = $YOUval password = $YOUR_SECRET
val userAgent: String = "meh"val encoding: String = "UTF-8" val HttpRequestTimeout: Int = 15000
var cookies = Map[String, String]()
def loadCookies(conn: URLConnection) { for ((name, value) <- cookies) conn.setRequestProperty("Cookie", name + "=" + value) }
def saveCookies(conn: URLConnection) { conn.getHeaderFields.lift("Set-Cookie") match { case Some(cList) => cList foreach { c => val (name,value) = c span { _ != '=' } cookies += name -> (value drop 1) // println("yum! "+ (name, (value drop 1))) } case None => }}
def Get(url: String) = { val u = new URL(url) val conn = u.openConnection().asInstanceOf[HttpURLConnection] conn.setRequestProperty("User-Agent", userAgent) conn.setConnectTimeout(HttpRequestTimeout)
val userPassword = username + ":" + password conn.setRequestProperty("Authorization", "Basic " + (new sun.misc.BASE64Encoder()).encode(userPassword.getBytes()))
conn.setDoInput(true) loadCookies(conn) conn.connect() saveCookies(conn)
val res = Source.fromInputStream(conn.getInputStream).getLines().mkString conn.disconnect() res}
def postJson(url: String, jobj: JSONObject) = { val u = new URL(url) val conn = u.openConnection.asInstanceOf[HttpURLConnection]
conn.setRequestProperty("User-Agent", userAgent) conn.setConnectTimeout(HttpRequestTimeout) // conn.setChunkedStreamingMode(0) conn.setRequestMethod("POST") conn.setRequestProperty("Content-Type", "application/json") val userPassword = username + ":" + password conn.setRequestProperty("Authorization", "Basic " + (new sun.misc.BASE64Encoder()).encode(userPassword.getBytes()))
loadCookies(conn)
conn.setDoOutput(true) conn.connect
val wr = new OutputStreamWriter(conn.getOutputStream()) // println("writing "+ jobj.toString()) wr.write(jobj.toString()) wr.flush
saveCookies(conn)
// println("" + conn.getResponseCode) val res = Source.fromInputStream(conn.getInputStream).getLines().mkString conn.disconnect() res}
import scala.util.parsing.json.JSONObjectobject JO { def apply(elems: (String, Any)*) = new JSONObject(Map(elems :_*)) }
// now let's work on our issues in the REPL
scala> postJson("https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions", JO("transition" -> "12")) res5: String = ""
scala> Get("https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions") res6: String = {"2":{"name":"Close Issue","fields":[{"id":"resolution","required":true,"type":"com.atlassian.jira.issue.resolution.Resolution"},{"id":"fixVersions","required":false,"type":"com.atlassian.jira.project.version.Version"},{"id":"assignee","required":false,"type":"com.opensymphony.user.User"}]}}
postJson("https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions", JO("transition" -> "2", "fields" -> JO("resolution" -> "Incomplete"), "comment" -> "Just testing the REST client."))
but it works and I had fun :-)
// cobbled together using the internets (mostly stackoverflow)// http://stackoverflow.com/questions/5564074/scala-http-operations/5571782#5571782 // http://stackoverflow.com/questions/4883100/how-to-handle-http-authentication-using-httpurlconnection/4883890#4883890 // JIRA's REST docs: http://docs.atlassian.com/jira/REST/latest/ (note that I couldn't figure out how to login by posting application/json -- using crude https basic auth)
import java.io.{OutputStreamWriter, BufferedReader, InputStreamReader}import java.net.{URLConnection, HttpURLConnection, URL}import scala.collection.JavaConversions._import scala.io.Source import java.net.URLEncoder.encode
val username = $YOUval password = $YOUR_SECRET
val userAgent: String = "meh"val encoding: String = "UTF-8" val HttpRequestTimeout: Int = 15000
var cookies = Map[String, String]()
def loadCookies(conn: URLConnection) { for ((name, value) <- cookies) conn.setRequestProperty("Cookie", name + "=" + value) }
def saveCookies(conn: URLConnection) { conn.getHeaderFields.lift("Set-Cookie") match { case Some(cList) => cList foreach { c => val (name,value) = c span { _ != '=' } cookies += name -> (value drop 1) // println("yum! "+ (name, (value drop 1))) } case None => }}
def Get(url: String) = { val u = new URL(url) val conn = u.openConnection().asInstanceOf[HttpURLConnection] conn.setRequestProperty("User-Agent", userAgent) conn.setConnectTimeout(HttpRequestTimeout)
val userPassword = username + ":" + password conn.setRequestProperty("Authorization", "Basic " + (new sun.misc.BASE64Encoder()).encode(userPassword.getBytes()))
conn.setDoInput(true) loadCookies(conn) conn.connect() saveCookies(conn)
val res = Source.fromInputStream(conn.getInputStream).getLines().mkString conn.disconnect() res}
def postJson(url: String, jobj: JSONObject) = { val u = new URL(url) val conn = u.openConnection.asInstanceOf[HttpURLConnection]
conn.setRequestProperty("User-Agent", userAgent) conn.setConnectTimeout(HttpRequestTimeout) // conn.setChunkedStreamingMode(0) conn.setRequestMethod("POST") conn.setRequestProperty("Content-Type", "application/json") val userPassword = username + ":" + password conn.setRequestProperty("Authorization", "Basic " + (new sun.misc.BASE64Encoder()).encode(userPassword.getBytes()))
loadCookies(conn)
conn.setDoOutput(true) conn.connect
val wr = new OutputStreamWriter(conn.getOutputStream()) // println("writing "+ jobj.toString()) wr.write(jobj.toString()) wr.flush
saveCookies(conn)
// println("" + conn.getResponseCode) val res = Source.fromInputStream(conn.getInputStream).getLines().mkString conn.disconnect() res}
import scala.util.parsing.json.JSONObjectobject JO { def apply(elems: (String, Any)*) = new JSONObject(Map(elems :_*)) }
// now let's work on our issues in the REPL
scala> postJson("https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions", JO("transition" -> "12")) res5: String = ""
scala> Get("https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions") res6: String = {"2":{"name":"Close Issue","fields":[{"id":"resolution","required":true,"type":"com.atlassian.jira.issue.resolution.Resolution"},{"id":"fixVersions","required":false,"type":"com.atlassian.jira.project.version.Version"},{"id":"assignee","required":false,"type":"com.opensymphony.user.User"}]}}
postJson("https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions", JO("transition" -> "2", "fields" -> JO("resolution" -> "Incomplete"), "comment" -> "Just testing the REST client."))
Tue, 2011-05-24, 11:57
#6
Re: Re: Trac -> Jira
thanks! :)
On Tue, May 24, 2011 at 11:51, Adriaan Moors <adriaan.moors@epfl.ch> wrote:
On Tue, May 24, 2011 at 11:51, Adriaan Moors <adriaan.moors@epfl.ch> wrote:
I couldn't resist cobbling together an abomination of my ownobvious improvements would be to use lift-json, implement decent authentication,...
but it works and I had fun :-)
// cobbled together using the internets (mostly stackoverflow)// http://stackoverflow.com/questions/5564074/scala-http-operations/5571782#5571782 // http://stackoverflow.com/questions/4883100/how-to-handle-http-authentication-using-httpurlconnection/4883890#4883890 // JIRA's REST docs: http://docs.atlassian.com/jira/REST/latest/ (note that I couldn't figure out how to login by posting application/json -- using crude https basic auth)
import java.io.{OutputStreamWriter, BufferedReader, InputStreamReader}import java.net.{URLConnection, HttpURLConnection, URL}import scala.collection.JavaConversions._import scala.io.Source import java.net.URLEncoder.encode
val username = $YOUval password = $YOUR_SECRET
val userAgent: String = "meh"val encoding: String = "UTF-8" val HttpRequestTimeout: Int = 15000
var cookies = Map[String, String]()
def loadCookies(conn: URLConnection) { for ((name, value) <- cookies) conn.setRequestProperty("Cookie", name + "=" + value) }
def saveCookies(conn: URLConnection) { conn.getHeaderFields.lift("Set-Cookie") match { case Some(cList) => cList foreach { c => val (name,value) = c span { _ != '=' } cookies += name -> (value drop 1) // println("yum! "+ (name, (value drop 1))) } case None => }}
def Get(url: String) = { val u = new URL(url) val conn = u.openConnection().asInstanceOf[HttpURLConnection] conn.setRequestProperty("User-Agent", userAgent) conn.setConnectTimeout(HttpRequestTimeout)
val userPassword = username + ":" + password conn.setRequestProperty("Authorization", "Basic " + (new sun.misc.BASE64Encoder()).encode(userPassword.getBytes()))
conn.setDoInput(true) loadCookies(conn) conn.connect() saveCookies(conn)
val res = Source.fromInputStream(conn.getInputStream).getLines().mkString conn.disconnect() res}
def postJson(url: String, jobj: JSONObject) = { val u = new URL(url) val conn = u.openConnection.asInstanceOf[HttpURLConnection]
conn.setRequestProperty("User-Agent", userAgent) conn.setConnectTimeout(HttpRequestTimeout) // conn.setChunkedStreamingMode(0) conn.setRequestMethod("POST") conn.setRequestProperty("Content-Type", "application/json") val userPassword = username + ":" + password conn.setRequestProperty("Authorization", "Basic " + (new sun.misc.BASE64Encoder()).encode(userPassword.getBytes()))
loadCookies(conn)
conn.setDoOutput(true) conn.connect
val wr = new OutputStreamWriter(conn.getOutputStream()) // println("writing "+ jobj.toString()) wr.write(jobj.toString()) wr.flush
saveCookies(conn)
// println("" + conn.getResponseCode) val res = Source.fromInputStream(conn.getInputStream).getLines().mkString conn.disconnect() res}
import scala.util.parsing.json.JSONObjectobject JO { def apply(elems: (String, Any)*) = new JSONObject(Map(elems :_*)) }
// now let's work on our issues in the REPL
scala> postJson("https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions", JO("transition" -> "12")) res5: String = ""
scala> Get("https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions") res6: String = {"2":{"name":"Close Issue","fields":[{"id":"resolution","required":true,"type":"com.atlassian.jira.issue.resolution.Resolution"},{"id":"fixVersions","required":false,"type":"com.atlassian.jira.project.version.Version"},{"id":"assignee","required":false,"type":"com.opensymphony.user.User"}]}}
postJson("https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions", JO("transition" -> "2", "fields" -> JO("resolution" -> "Incomplete"), "comment" -> "Just testing the REST client."))
Tue, 2011-05-24, 12:27
#7
Re: Re: Trac -> Jira
Why not use the dispatch library for posts and gets? it is ridiculuosly easy and supports auth.
On May 24, 2011 6:52 AM, "Lukas Rytz" <lukas.rytz@epfl.ch> wrote:> thanks! :)
>
> On Tue, May 24, 2011 at 11:51, Adriaan Moors <adriaan.moors@epfl.ch> wrote:
>
>> I couldn't resist cobbling together an abomination of my own
>> obvious improvements would be to use lift-json, implement decent
>> authentication,...
>>
>> but it works and I had fun :-)
>>
>> // cobbled together using the internets (mostly stackoverflow)
>> //
>> http://stackoverflow.com/questions/5564074/scala-http-operations/5571782#5571782
>> //
>> http://stackoverflow.com/questions/4883100/how-to-handle-http-authentication-using-httpurlconnection/4883890#4883890
>> // JIRA's REST docs: http://docs.atlassian.com/jira/REST/latest/ (note
>> that I couldn't figure out how to login by posting application/json -- using
>> crude https basic auth)
>>
>> import java.io.{OutputStreamWriter, BufferedReader, InputStreamReader}
>> import java.net.{URLConnection, HttpURLConnection, URL}
>> import scala.collection.JavaConversions._
>> import scala.io.Source
>> import java.net.URLEncoder.encode
>>
>> val username = $YOU
>> val password = $YOUR_SECRET
>>
>> val userAgent: String = "meh"
>> val encoding: String = "UTF-8"
>> val HttpRequestTimeout: Int = 15000
>>
>> var cookies = Map[String, String]()
>>
>> def loadCookies(conn: URLConnection) {
>> for ((name, value) <- cookies) conn.setRequestProperty("Cookie", name +
>> "=" + value)
>> }
>>
>> def saveCookies(conn: URLConnection) {
>> conn.getHeaderFields.lift("Set-Cookie") match {
>> case Some(cList) => cList foreach { c =>
>> val (name,value) = c span { _ != '=' }
>> cookies += name -> (value drop 1)
>> // println("yum! "+ (name, (value drop 1)))
>> }
>> case None =>
>> }
>> }
>>
>> def Get(url: String) = {
>> val u = new URL(url)
>> val conn = u.openConnection().asInstanceOf[HttpURLConnection]
>> conn.setRequestProperty("User-Agent", userAgent)
>> conn.setConnectTimeout(HttpRequestTimeout)
>>
>> val userPassword = username + ":" + password
>> conn.setRequestProperty("Authorization", "Basic " + (new
>> sun.misc.BASE64Encoder()).encode(userPassword.getBytes()))
>>
>> conn.setDoInput(true)
>> loadCookies(conn)
>> conn.connect()
>> saveCookies(conn)
>>
>> val res = Source.fromInputStream(conn.getInputStream).getLines().mkString
>> conn.disconnect()
>> res
>> }
>>
>> def postJson(url: String, jobj: JSONObject) = {
>> val u = new URL(url)
>> val conn = u.openConnection.asInstanceOf[HttpURLConnection]
>>
>> conn.setRequestProperty("User-Agent", userAgent)
>> conn.setConnectTimeout(HttpRequestTimeout)
>> // conn.setChunkedStreamingMode(0)
>> conn.setRequestMethod("POST")
>> conn.setRequestProperty("Content-Type", "application/json")
>> val userPassword = username + ":" + password
>> conn.setRequestProperty("Authorization", "Basic " + (new
>> sun.misc.BASE64Encoder()).encode(userPassword.getBytes()))
>>
>> loadCookies(conn)
>>
>> conn.setDoOutput(true)
>> conn.connect
>>
>> val wr = new OutputStreamWriter(conn.getOutputStream())
>> // println("writing "+ jobj.toString())
>> wr.write(jobj.toString())
>> wr.flush
>>
>> saveCookies(conn)
>>
>> // println("" + conn.getResponseCode)
>> val res = Source.fromInputStream(conn.getInputStream).getLines().mkString
>> conn.disconnect()
>> res
>> }
>>
>>
>> import scala.util.parsing.json.JSONObject
>> object JO { def apply(elems: (String, Any)*) = new JSONObject(Map(elems
>> :_*)) }
>>
>> // now let's work on our issues in the REPL
>>
>> scala> postJson("
>> https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions",
>> JO("transition" -> "12"))
>> res5: String = ""
>>
>> scala> Get("
>> https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions
>> ")
>> res6: String = {"2":{"name":"Close
>> Issue","fields":[{"id":"resolution","required":true,"type":"com.atlassian.jira.issue.resolution.Resolution"},{"id":"fixVersions","required":false,"type":"com.atlassian.jira.project.version.Version"},{"id":"assignee","required":false,"type":"com.opensymphony.user.User"}]}}
>>
>>
>> postJson("
>> https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions",
>> JO("transition" -> "2", "fields" -> JO("resolution" -> "Incomplete"),
>> "comment" -> "Just testing the REST client."))
>>
>>
Tue, 2011-05-24, 13:57
#8
Re: Re: Trac -> Jira
sure! great! please do :-)
my code is just a proof of concept that does not use any external dependencies -- a decent http client and json parser are surely worthy improvements/dependencies
adriaan
On Tue, May 24, 2011 at 1:25 PM, Josh Suereth <joshua.suereth@gmail.com> wrote:
my code is just a proof of concept that does not use any external dependencies -- a decent http client and json parser are surely worthy improvements/dependencies
adriaan
On Tue, May 24, 2011 at 1:25 PM, Josh Suereth <joshua.suereth@gmail.com> wrote:
Why not use the dispatch library for posts and gets? it is ridiculuosly easy and supports auth.
On May 24, 2011 6:52 AM, "Lukas Rytz" <lukas.rytz@epfl.ch> wrote:
> thanks! :)
>
> On Tue, May 24, 2011 at 11:51, Adriaan Moors <adriaan.moors@epfl.ch> wrote:
>
>> I couldn't resist cobbling together an abomination of my own
>> obvious improvements would be to use lift-json, implement decent
>> authentication,...
>>
>> but it works and I had fun :-)
>>
>> // cobbled together using the internets (mostly stackoverflow)
>> //
>> http://stackoverflow.com/questions/5564074/scala-http-operations/5571782#5571782
>> //
>> http://stackoverflow.com/questions/4883100/how-to-handle-http-authentication-using-httpurlconnection/4883890#4883890
>> // JIRA's REST docs: http://docs.atlassian.com/jira/REST/latest/ (note
>> that I couldn't figure out how to login by posting application/json -- using
>> crude https basic auth)
>>
>> import java.io.{OutputStreamWriter, BufferedReader, InputStreamReader}
>> import java.net.{URLConnection, HttpURLConnection, URL}
>> import scala.collection.JavaConversions._
>> import scala.io.Source
>> import java.net.URLEncoder.encode
>>
>> val username = $YOU
>> val password = $YOUR_SECRET
>>
>> val userAgent: String = "meh"
>> val encoding: String = "UTF-8"
>> val HttpRequestTimeout: Int = 15000
>>
>> var cookies = Map[String, String]()
>>
>> def loadCookies(conn: URLConnection) {
>> for ((name, value) <- cookies) conn.setRequestProperty("Cookie", name +
>> "=" + value)
>> }
>>
>> def saveCookies(conn: URLConnection) {
>> conn.getHeaderFields.lift("Set-Cookie") match {
>> case Some(cList) => cList foreach { c =>
>> val (name,value) = c span { _ != '=' }
>> cookies += name -> (value drop 1)
>> // println("yum! "+ (name, (value drop 1)))
>> }
>> case None =>
>> }
>> }
>>
>> def Get(url: String) = {
>> val u = new URL(url)
>> val conn = u.openConnection().asInstanceOf[HttpURLConnection]
>> conn.setRequestProperty("User-Agent", userAgent)
>> conn.setConnectTimeout(HttpRequestTimeout)
>>
>> val userPassword = username + ":" + password
>> conn.setRequestProperty("Authorization", "Basic " + (new
>> sun.misc.BASE64Encoder()).encode(userPassword.getBytes()))
>>
>> conn.setDoInput(true)
>> loadCookies(conn)
>> conn.connect()
>> saveCookies(conn)
>>
>> val res = Source.fromInputStream(conn.getInputStream).getLines().mkString
>> conn.disconnect()
>> res
>> }
>>
>> def postJson(url: String, jobj: JSONObject) = {
>> val u = new URL(url)
>> val conn = u.openConnection.asInstanceOf[HttpURLConnection]
>>
>> conn.setRequestProperty("User-Agent", userAgent)
>> conn.setConnectTimeout(HttpRequestTimeout)
>> // conn.setChunkedStreamingMode(0)
>> conn.setRequestMethod("POST")
>> conn.setRequestProperty("Content-Type", "application/json")
>> val userPassword = username + ":" + password
>> conn.setRequestProperty("Authorization", "Basic " + (new
>> sun.misc.BASE64Encoder()).encode(userPassword.getBytes()))
>>
>> loadCookies(conn)
>>
>> conn.setDoOutput(true)
>> conn.connect
>>
>> val wr = new OutputStreamWriter(conn.getOutputStream())
>> // println("writing "+ jobj.toString())
>> wr.write(jobj.toString())
>> wr.flush
>>
>> saveCookies(conn)
>>
>> // println("" + conn.getResponseCode)
>> val res = Source.fromInputStream(conn.getInputStream).getLines().mkString
>> conn.disconnect()
>> res
>> }
>>
>>
>> import scala.util.parsing.json.JSONObject
>> object JO { def apply(elems: (String, Any)*) = new JSONObject(Map(elems
>> :_*)) }
>>
>> // now let's work on our issues in the REPL
>>
>> scala> postJson("
>> https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions",
>> JO("transition" -> "12"))
>> res5: String = ""
>>
>> scala> Get("
>> https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions
>> ")
>> res6: String = {"2":{"name":"Close
>> Issue","fields":[{"id":"resolution","required":true,"type":"com.atlassian.jira.issue.resolution.Resolution"},{"id":"fixVersions","required":false,"type":"com.atlassian.jira.project.version.Version"},{"id":"assignee","required":false,"type":"com.opensymphony.user.User"}]}}
>>
>>
>> postJson("
>> https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions",
>> JO("transition" -> "2", "fields" -> JO("resolution" -> "Incomplete"),
>> "comment" -> "Just testing the REST client."))
>>
>>
Tue, 2011-05-24, 17:27
#9
Re: Re: Trac -> Jira
tinkered with it some more -- still avoiding external dependencies, but now doing the bare minimum of json processing for a post-commit script
adriaan
ps: this could be made more efficient (e.g., closing an issue requires a GET&POST instead of just a POST)
On Tue, May 24, 2011 at 2:50 PM, Adriaan Moors <adriaan.moors@epfl.ch> wrote:
adriaan
ps: this could be made more efficient (e.g., closing an issue requires a GET&POST instead of just a POST)
On Tue, May 24, 2011 at 2:50 PM, Adriaan Moors <adriaan.moors@epfl.ch> wrote:
sure! great! please do :-)
my code is just a proof of concept that does not use any external dependencies -- a decent http client and json parser are surely worthy improvements/dependencies
adriaan
On Tue, May 24, 2011 at 1:25 PM, Josh Suereth <joshua.suereth@gmail.com> wrote:
Why not use the dispatch library for posts and gets? it is ridiculuosly easy and supports auth.
On May 24, 2011 6:52 AM, "Lukas Rytz" <lukas.rytz@epfl.ch> wrote:
> thanks! :)
>
> On Tue, May 24, 2011 at 11:51, Adriaan Moors <adriaan.moors@epfl.ch> wrote:
>
>> I couldn't resist cobbling together an abomination of my own
>> obvious improvements would be to use lift-json, implement decent
>> authentication,...
>>
>> but it works and I had fun :-)
>>
>> // cobbled together using the internets (mostly stackoverflow)
>> //
>> http://stackoverflow.com/questions/5564074/scala-http-operations/5571782#5571782
>> //
>> http://stackoverflow.com/questions/4883100/how-to-handle-http-authentication-using-httpurlconnection/4883890#4883890
>> // JIRA's REST docs: http://docs.atlassian.com/jira/REST/latest/ (note
>> that I couldn't figure out how to login by posting application/json -- using
>> crude https basic auth)
>>
>> import java.io.{OutputStreamWriter, BufferedReader, InputStreamReader}
>> import java.net.{URLConnection, HttpURLConnection, URL}
>> import scala.collection.JavaConversions._
>> import scala.io.Source
>> import java.net.URLEncoder.encode
>>
>> val username = $YOU
>> val password = $YOUR_SECRET
>>
>> val userAgent: String = "meh"
>> val encoding: String = "UTF-8"
>> val HttpRequestTimeout: Int = 15000
>>
>> var cookies = Map[String, String]()
>>
>> def loadCookies(conn: URLConnection) {
>> for ((name, value) <- cookies) conn.setRequestProperty("Cookie", name +
>> "=" + value)
>> }
>>
>> def saveCookies(conn: URLConnection) {
>> conn.getHeaderFields.lift("Set-Cookie") match {
>> case Some(cList) => cList foreach { c =>
>> val (name,value) = c span { _ != '=' }
>> cookies += name -> (value drop 1)
>> // println("yum! "+ (name, (value drop 1)))
>> }
>> case None =>
>> }
>> }
>>
>> def Get(url: String) = {
>> val u = new URL(url)
>> val conn = u.openConnection().asInstanceOf[HttpURLConnection]
>> conn.setRequestProperty("User-Agent", userAgent)
>> conn.setConnectTimeout(HttpRequestTimeout)
>>
>> val userPassword = username + ":" + password
>> conn.setRequestProperty("Authorization", "Basic " + (new
>> sun.misc.BASE64Encoder()).encode(userPassword.getBytes()))
>>
>> conn.setDoInput(true)
>> loadCookies(conn)
>> conn.connect()
>> saveCookies(conn)
>>
>> val res = Source.fromInputStream(conn.getInputStream).getLines().mkString
>> conn.disconnect()
>> res
>> }
>>
>> def postJson(url: String, jobj: JSONObject) = {
>> val u = new URL(url)
>> val conn = u.openConnection.asInstanceOf[HttpURLConnection]
>>
>> conn.setRequestProperty("User-Agent", userAgent)
>> conn.setConnectTimeout(HttpRequestTimeout)
>> // conn.setChunkedStreamingMode(0)
>> conn.setRequestMethod("POST")
>> conn.setRequestProperty("Content-Type", "application/json")
>> val userPassword = username + ":" + password
>> conn.setRequestProperty("Authorization", "Basic " + (new
>> sun.misc.BASE64Encoder()).encode(userPassword.getBytes()))
>>
>> loadCookies(conn)
>>
>> conn.setDoOutput(true)
>> conn.connect
>>
>> val wr = new OutputStreamWriter(conn.getOutputStream())
>> // println("writing "+ jobj.toString())
>> wr.write(jobj.toString())
>> wr.flush
>>
>> saveCookies(conn)
>>
>> // println("" + conn.getResponseCode)
>> val res = Source.fromInputStream(conn.getInputStream).getLines().mkString
>> conn.disconnect()
>> res
>> }
>>
>>
>> import scala.util.parsing.json.JSONObject
>> object JO { def apply(elems: (String, Any)*) = new JSONObject(Map(elems
>> :_*)) }
>>
>> // now let's work on our issues in the REPL
>>
>> scala> postJson("
>> https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions",
>> JO("transition" -> "12"))
>> res5: String = ""
>>
>> scala> Get("
>> https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions
>> ")
>> res6: String = {"2":{"name":"Close
>> Issue","fields":[{"id":"resolution","required":true,"type":"com.atlassian.jira.issue.resolution.Resolution"},{"id":"fixVersions","required":false,"type":"com.atlassian.jira.project.version.Version"},{"id":"assignee","required":false,"type":"com.opensymphony.user.User"}]}}
>>
>>
>> postJson("
>> https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions",
>> JO("transition" -> "2", "fields" -> JO("resolution" -> "Incomplete"),
>> "comment" -> "Just testing the REST client."))
>>
>>
Tue, 2011-05-24, 17:37
#10
Re: Re: Trac -> Jira
Just be thankful you don't have to target the SOAP interface!
On 24 May 2011 17:19, Adriaan Moors <adriaan.moors@epfl.ch> wrote:
--
Kevin Wright
gtalk / msn : kev.lee.wright@gmail.comkev.lee.wright@gmail.commail: kevin.wright@scalatechnology.com
vibe / skype: kev.lee.wrightquora: http://www.quora.com/Kevin-Wright
twitter: @thecoda
"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra
On 24 May 2011 17:19, Adriaan Moors <adriaan.moors@epfl.ch> wrote:
tinkered with it some more -- still avoiding external dependencies, but now doing the bare minimum of json processing for a post-commit script
adriaan
ps: this could be made more efficient (e.g., closing an issue requires a GET&POST instead of just a POST)
On Tue, May 24, 2011 at 2:50 PM, Adriaan Moors <adriaan.moors@epfl.ch> wrote:sure! great! please do :-)
my code is just a proof of concept that does not use any external dependencies -- a decent http client and json parser are surely worthy improvements/dependencies
adriaan
On Tue, May 24, 2011 at 1:25 PM, Josh Suereth <joshua.suereth@gmail.com> wrote:
Why not use the dispatch library for posts and gets? it is ridiculuosly easy and supports auth.
On May 24, 2011 6:52 AM, "Lukas Rytz" <lukas.rytz@epfl.ch> wrote:
> thanks! :)
>
> On Tue, May 24, 2011 at 11:51, Adriaan Moors <adriaan.moors@epfl.ch> wrote:
>
>> I couldn't resist cobbling together an abomination of my own
>> obvious improvements would be to use lift-json, implement decent
>> authentication,...
>>
>> but it works and I had fun :-)
>>
>> // cobbled together using the internets (mostly stackoverflow)
>> //
>> http://stackoverflow.com/questions/5564074/scala-http-operations/5571782#5571782
>> //
>> http://stackoverflow.com/questions/4883100/how-to-handle-http-authentication-using-httpurlconnection/4883890#4883890
>> // JIRA's REST docs: http://docs.atlassian.com/jira/REST/latest/ (note
>> that I couldn't figure out how to login by posting application/json -- using
>> crude https basic auth)
>>
>> import java.io.{OutputStreamWriter, BufferedReader, InputStreamReader}
>> import java.net.{URLConnection, HttpURLConnection, URL}
>> import scala.collection.JavaConversions._
>> import scala.io.Source
>> import java.net.URLEncoder.encode
>>
>> val username = $YOU
>> val password = $YOUR_SECRET
>>
>> val userAgent: String = "meh"
>> val encoding: String = "UTF-8"
>> val HttpRequestTimeout: Int = 15000
>>
>> var cookies = Map[String, String]()
>>
>> def loadCookies(conn: URLConnection) {
>> for ((name, value) <- cookies) conn.setRequestProperty("Cookie", name +
>> "=" + value)
>> }
>>
>> def saveCookies(conn: URLConnection) {
>> conn.getHeaderFields.lift("Set-Cookie") match {
>> case Some(cList) => cList foreach { c =>
>> val (name,value) = c span { _ != '=' }
>> cookies += name -> (value drop 1)
>> // println("yum! "+ (name, (value drop 1)))
>> }
>> case None =>
>> }
>> }
>>
>> def Get(url: String) = {
>> val u = new URL(url)
>> val conn = u.openConnection().asInstanceOf[HttpURLConnection]
>> conn.setRequestProperty("User-Agent", userAgent)
>> conn.setConnectTimeout(HttpRequestTimeout)
>>
>> val userPassword = username + ":" + password
>> conn.setRequestProperty("Authorization", "Basic " + (new
>> sun.misc.BASE64Encoder()).encode(userPassword.getBytes()))
>>
>> conn.setDoInput(true)
>> loadCookies(conn)
>> conn.connect()
>> saveCookies(conn)
>>
>> val res = Source.fromInputStream(conn.getInputStream).getLines().mkString
>> conn.disconnect()
>> res
>> }
>>
>> def postJson(url: String, jobj: JSONObject) = {
>> val u = new URL(url)
>> val conn = u.openConnection.asInstanceOf[HttpURLConnection]
>>
>> conn.setRequestProperty("User-Agent", userAgent)
>> conn.setConnectTimeout(HttpRequestTimeout)
>> // conn.setChunkedStreamingMode(0)
>> conn.setRequestMethod("POST")
>> conn.setRequestProperty("Content-Type", "application/json")
>> val userPassword = username + ":" + password
>> conn.setRequestProperty("Authorization", "Basic " + (new
>> sun.misc.BASE64Encoder()).encode(userPassword.getBytes()))
>>
>> loadCookies(conn)
>>
>> conn.setDoOutput(true)
>> conn.connect
>>
>> val wr = new OutputStreamWriter(conn.getOutputStream())
>> // println("writing "+ jobj.toString())
>> wr.write(jobj.toString())
>> wr.flush
>>
>> saveCookies(conn)
>>
>> // println("" + conn.getResponseCode)
>> val res = Source.fromInputStream(conn.getInputStream).getLines().mkString
>> conn.disconnect()
>> res
>> }
>>
>>
>> import scala.util.parsing.json.JSONObject
>> object JO { def apply(elems: (String, Any)*) = new JSONObject(Map(elems
>> :_*)) }
>>
>> // now let's work on our issues in the REPL
>>
>> scala> postJson("
>> https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions",
>> JO("transition" -> "12"))
>> res5: String = ""
>>
>> scala> Get("
>> https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions
>> ")
>> res6: String = {"2":{"name":"Close
>> Issue","fields":[{"id":"resolution","required":true,"type":"com.atlassian.jira.issue.resolution.Resolution"},{"id":"fixVersions","required":false,"type":"com.atlassian.jira.project.version.Version"},{"id":"assignee","required":false,"type":"com.opensymphony.user.User"}]}}
>>
>>
>> postJson("
>> https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions",
>> JO("transition" -> "2", "fields" -> JO("resolution" -> "Incomplete"),
>> "comment" -> "Just testing the REST client."))
>>
>>
--
Kevin Wright
gtalk / msn : kev.lee.wright@gmail.comkev.lee.wright@gmail.commail: kevin.wright@scalatechnology.com
vibe / skype: kev.lee.wrightquora: http://www.quora.com/Kevin-Wright
twitter: @thecoda
"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra
Wed, 2011-05-25, 09:27
#11
Re: Re: Trac -> Jira
The script is now running.
There's a jenkins job polling SVN (later git) and calling a scala script whenever there's a change.
Syntax: - "close SI-1234, SI-234" closes issues - "close", "closes", "closed", "fix", "fixes", "fixed" are all identical - "reopen SI-2341" reopens issues - "reopen", "reopens", "reopened" are identical
- whenever a ticket number is mentioned outside "close" or "reopen", a comment is added to the corresponding ticket
- "SI-123", "SI_123", "SI123", "#1e1e1e" all work. but try to use the correct "SI-123", only this one will be understood by JIRA and converted to a link.
Lukas
On Tue, May 24, 2011 at 18:21, Kevin Wright <kev.lee.wright@gmail.com> wrote:
There's a jenkins job polling SVN (later git) and calling a scala script whenever there's a change.
Syntax: - "close SI-1234, SI-234" closes issues - "close", "closes", "closed", "fix", "fixes", "fixed" are all identical - "reopen SI-2341" reopens issues - "reopen", "reopens", "reopened" are identical
- whenever a ticket number is mentioned outside "close" or "reopen", a comment is added to the corresponding ticket
- "SI-123", "SI_123", "SI123", "#1e1e1e" all work. but try to use the correct "SI-123", only this one will be understood by JIRA and converted to a link.
Lukas
On Tue, May 24, 2011 at 18:21, Kevin Wright <kev.lee.wright@gmail.com> wrote:
Just be thankful you don't have to target the SOAP interface!
On 24 May 2011 17:19, Adriaan Moors <adriaan.moors@epfl.ch> wrote:
tinkered with it some more -- still avoiding external dependencies, but now doing the bare minimum of json processing for a post-commit script
adriaan
ps: this could be made more efficient (e.g., closing an issue requires a GET&POST instead of just a POST)
On Tue, May 24, 2011 at 2:50 PM, Adriaan Moors <adriaan.moors@epfl.ch> wrote:sure! great! please do :-)
my code is just a proof of concept that does not use any external dependencies -- a decent http client and json parser are surely worthy improvements/dependencies
adriaan
On Tue, May 24, 2011 at 1:25 PM, Josh Suereth <joshua.suereth@gmail.com> wrote:
Why not use the dispatch library for posts and gets? it is ridiculuosly easy and supports auth.
On May 24, 2011 6:52 AM, "Lukas Rytz" <lukas.rytz@epfl.ch> wrote:
> thanks! :)
>
> On Tue, May 24, 2011 at 11:51, Adriaan Moors <adriaan.moors@epfl.ch> wrote:
>
>> I couldn't resist cobbling together an abomination of my own
>> obvious improvements would be to use lift-json, implement decent
>> authentication,...
>>
>> but it works and I had fun :-)
>>
>> // cobbled together using the internets (mostly stackoverflow)
>> //
>> http://stackoverflow.com/questions/5564074/scala-http-operations/5571782#5571782
>> //
>> http://stackoverflow.com/questions/4883100/how-to-handle-http-authentication-using-httpurlconnection/4883890#4883890
>> // JIRA's REST docs: http://docs.atlassian.com/jira/REST/latest/ (note
>> that I couldn't figure out how to login by posting application/json -- using
>> crude https basic auth)
>>
>> import java.io.{OutputStreamWriter, BufferedReader, InputStreamReader}
>> import java.net.{URLConnection, HttpURLConnection, URL}
>> import scala.collection.JavaConversions._
>> import scala.io.Source
>> import java.net.URLEncoder.encode
>>
>> val username = $YOU
>> val password = $YOUR_SECRET
>>
>> val userAgent: String = "meh"
>> val encoding: String = "UTF-8"
>> val HttpRequestTimeout: Int = 15000
>>
>> var cookies = Map[String, String]()
>>
>> def loadCookies(conn: URLConnection) {
>> for ((name, value) <- cookies) conn.setRequestProperty("Cookie", name +
>> "=" + value)
>> }
>>
>> def saveCookies(conn: URLConnection) {
>> conn.getHeaderFields.lift("Set-Cookie") match {
>> case Some(cList) => cList foreach { c =>
>> val (name,value) = c span { _ != '=' }
>> cookies += name -> (value drop 1)
>> // println("yum! "+ (name, (value drop 1)))
>> }
>> case None =>
>> }
>> }
>>
>> def Get(url: String) = {
>> val u = new URL(url)
>> val conn = u.openConnection().asInstanceOf[HttpURLConnection]
>> conn.setRequestProperty("User-Agent", userAgent)
>> conn.setConnectTimeout(HttpRequestTimeout)
>>
>> val userPassword = username + ":" + password
>> conn.setRequestProperty("Authorization", "Basic " + (new
>> sun.misc.BASE64Encoder()).encode(userPassword.getBytes()))
>>
>> conn.setDoInput(true)
>> loadCookies(conn)
>> conn.connect()
>> saveCookies(conn)
>>
>> val res = Source.fromInputStream(conn.getInputStream).getLines().mkString
>> conn.disconnect()
>> res
>> }
>>
>> def postJson(url: String, jobj: JSONObject) = {
>> val u = new URL(url)
>> val conn = u.openConnection.asInstanceOf[HttpURLConnection]
>>
>> conn.setRequestProperty("User-Agent", userAgent)
>> conn.setConnectTimeout(HttpRequestTimeout)
>> // conn.setChunkedStreamingMode(0)
>> conn.setRequestMethod("POST")
>> conn.setRequestProperty("Content-Type", "application/json")
>> val userPassword = username + ":" + password
>> conn.setRequestProperty("Authorization", "Basic " + (new
>> sun.misc.BASE64Encoder()).encode(userPassword.getBytes()))
>>
>> loadCookies(conn)
>>
>> conn.setDoOutput(true)
>> conn.connect
>>
>> val wr = new OutputStreamWriter(conn.getOutputStream())
>> // println("writing "+ jobj.toString())
>> wr.write(jobj.toString())
>> wr.flush
>>
>> saveCookies(conn)
>>
>> // println("" + conn.getResponseCode)
>> val res = Source.fromInputStream(conn.getInputStream).getLines().mkString
>> conn.disconnect()
>> res
>> }
>>
>>
>> import scala.util.parsing.json.JSONObject
>> object JO { def apply(elems: (String, Any)*) = new JSONObject(Map(elems
>> :_*)) }
>>
>> // now let's work on our issues in the REPL
>>
>> scala> postJson("
>> https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions",
>> JO("transition" -> "12"))
>> res5: String = ""
>>
>> scala> Get("
>> https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions
>> ")
>> res6: String = {"2":{"name":"Close
>> Issue","fields":[{"id":"resolution","required":true,"type":"com.atlassian.jira.issue.resolution.Resolution"},{"id":"fixVersions","required":false,"type":"com.atlassian.jira.project.version.Version"},{"id":"assignee","required":false,"type":"com.opensymphony.user.User"}]}}
>>
>>
>> postJson("
>> https://issues.scala-lang.org/rest/api/2.0.alpha1/issue/SI-4637/transitions",
>> JO("transition" -> "2", "fields" -> JO("resolution" -> "Incomplete"),
>> "comment" -> "Just testing the REST client."))
>>
>>
--
Kevin Wright
gtalk / msn : kev.lee.wright@gmail.comkev.lee.wright@gmail.commail: kevin.wright@scalatechnology.com
vibe / skype: kev.lee.wrightquora: http://www.quora.com/Kevin-Wright
twitter: @thecoda
"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra
So we probably have to do it with either - A Plugin http://confluence.atlassian.com/display/JIRA043/JIRA+Development+Hub - The SOAP API http://confluence.atlassian.com/display/JIRA/Creating+a+SOAP+Client - The REST API http://docs.atlassian.com/jira/REST/latest/
On Mon, May 23, 2011 at 11:57, Fabien Salvi <fabien.salvi@epfl.ch> wrote: