Giter Site home page Giter Site logo

kanboard-import-trello's People

Contributors

daangemist avatar kanocz avatar mbyakow avatar psy-q avatar tpokorra avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

kanboard-import-trello's Issues

Malformed payload when listing projects

I had to mess around a bit because I was unable to make import.php connect to a server with an invalid certificate. That's why I switched to a newer version of json-rpc in #9 so that I could disable cert verification.

After that I still couldn't make it work. Below is a log with debug enabled. I verified that it works fine when done manually using curl. Curl example is on the bottom.

# These are some debug var_dumps that I stuck there, to make sure the payload
# is passed correctly
in execute:string(57) "{"jsonrpc":"2.0","method":"getAllProjects","id":17746587}"
in sendPayload:string(57) "{"jsonrpc":"2.0","method":"getAllProjects","id":17746587}"
in sendPayload but after execute:==> Request: 
{"jsonrpc":"2.0","method":"getAllProjects","id":17746587}
==> Headers: 
array (
  0 => 'HTTP/1.1 302 Found',
  1 => 'Date: Thu, 02 Feb 2017 12:26:51 GMT',
  2 => 'Server: Apache/2.4.10 (Debian)',
  3 => 'Set-Cookie: KB_SID=BZD-E9IHesgk2FxuWWPzJrqGeS8; path=/; secure; HttpOnly',
  4 => 'Expires: Thu, 19 Nov 1981 08:52:00 GMT',
  5 => 'Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0',
  6 => 'Pragma: no-cache',
  7 => 'Content-Security-Policy: default-src \'self\'; style-src \'self\' \'unsafe-inline\'; img-src * data:;',
  8 => 'X-Content-Type-Options: nosniff',
  9 => 'X-XSS-Protection: 1; mode=block',
  10 => 'P3P: CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"',
  11 => 'X-Frame-Options: DENY',
  12 => 'Strict-Transport-Security: max-age=31536000',
  13 => 'Location: /?controller=AuthController&action=login',
  14 => 'Content-Length: 0',
  15 => 'Connection: close',
  16 => 'Content-Type: text/html; charset=UTF-8',
  17 => 'HTTP/1.1 200 OK',
  18 => 'Date: Thu, 02 Feb 2017 12:26:52 GMT',
  19 => 'Server: Apache/2.4.10 (Debian)',
  20 => 'Set-Cookie: KB_SID=8fr%2CdO7xUpS%2CAzUMqfwB5iMVDH2; path=/; secure; HttpOnly',
  21 => 'Expires: Thu, 19 Nov 1981 08:52:00 GMT',
  22 => 'Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0',
  23 => 'Pragma: no-cache',
  24 => 'Content-Security-Policy: default-src \'self\'; style-src \'self\' \'unsafe-inline\'; img-src * data:;',
  25 => 'X-Content-Type-Options: nosniff',
  26 => 'X-XSS-Protection: 1; mode=block',
  27 => 'P3P: CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"',
  28 => 'X-Frame-Options: DENY',
  29 => 'Strict-Transport-Security: max-age=31536000',
  30 => 'Vary: Accept-Encoding',
  31 => 'Content-Length: 4848',
  32 => 'Connection: close',
  33 => 'Content-Type: text/html; charset=utf-8',
)
==> Response: 
null
NULL
==> Request: 
{"jsonrpc":"2.0","method":"getAllProjects","id":17746587}
==> Headers: 
array (
  0 => 'HTTP/1.1 302 Found',
  1 => 'Date: Thu, 02 Feb 2017 12:26:52 GMT',
  2 => 'Server: Apache/2.4.10 (Debian)',
  3 => 'Expires: Thu, 19 Nov 1981 08:52:00 GMT',
  4 => 'Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0',
  5 => 'Pragma: no-cache',
  6 => 'Content-Security-Policy: default-src \'self\'; style-src \'self\' \'unsafe-inline\'; img-src * data:;',
  7 => 'X-Content-Type-Options: nosniff',
  8 => 'X-XSS-Protection: 1; mode=block',
  9 => 'P3P: CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"',
  10 => 'X-Frame-Options: DENY',
  11 => 'Strict-Transport-Security: max-age=31536000',
  12 => 'Location: /?controller=AuthController&action=login',
  13 => 'Content-Length: 0',
  14 => 'Connection: close',
  15 => 'Content-Type: text/html; charset=UTF-8',
  16 => 'HTTP/1.1 200 OK',
  17 => 'Date: Thu, 02 Feb 2017 12:26:52 GMT',
  18 => 'Server: Apache/2.4.10 (Debian)',
  19 => 'Expires: Thu, 19 Nov 1981 08:52:00 GMT',
  20 => 'Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0',
  21 => 'Pragma: no-cache',
  22 => 'Content-Security-Policy: default-src \'self\'; style-src \'self\' \'unsafe-inline\'; img-src * data:;',
  23 => 'X-Content-Type-Options: nosniff',
  24 => 'X-XSS-Protection: 1; mode=block',
  25 => 'P3P: CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"',
  26 => 'X-Frame-Options: DENY',
  27 => 'Strict-Transport-Security: max-age=31536000',
  28 => 'Vary: Accept-Encoding',
  29 => 'Content-Length: 4848',
  30 => 'Connection: close',
  31 => 'Content-Type: text/html; charset=utf-8',
)
==> Response: 
null
in parse:NULL
PHP Fatal error:  Uncaught exception 'JsonRPC\Exception\InvalidJsonFormatException' with message 'Malformed payload' in /home/rca/kanboard-import-trello/vendor/fguillot/json-rpc/src/JsonRPC/Validator/JsonFormatValidator.php:26
Stack trace:
#0 /home/rca/kanboard-import-trello/vendor/fguillot/json-rpc/src/JsonRPC/Response/ResponseParser.php(88): JsonRPC\Validator\JsonFormatValidator::validate(NULL)
#1 /home/rca/kanboard-import-trello/vendor/fguillot/json-rpc/src/JsonRPC/Client.php(204): JsonRPC\Response\ResponseParser->parse()
#2 /home/rca/kanboard-import-trello/vendor/fguillot/json-rpc/src/JsonRPC/Client.php(182): JsonRPC\Client->sendPayload('{"jsonrpc":"2.0...')
#3 /home/rca/kanboard-import-trello/vendor/fguillot/json-rpc/src/JsonRPC/Client.php(126): JsonRPC\Client->execute('getAllProjects', Array)
#4 /home/rca/kanboard-import-trello/import.php(58): JsonRPC\Client->__call('getAllProjects', Array)
#5 /home/rca/kanboard-import-trello/import.php(58): JsonRPC\Client->getAllProjects()
#6 {main}
  thrown in /home/rca/kanboard-import-trello/vendor/fguillot/json-rpc/src/JsonRPC/Validator/JsonFormatValidator.php on line 26

These are examples with curl:

curl -k -d @/tmp/test_request.json -u jsonrpc:token-redacted  https://pm.zhdk.ch/jsonrpc.php
{"jsonrpc":"2.0","result":[{"id":"1","name":"Testprojekt","is_active":"1","token":"","last_modified":"1486031601","is_public":"0","is_private":"0","is_everybody_allowed":"0","default_swimlane":"Default swimlane","show_default_swimlane":"1","description":null,"identifier":"","start_date":"","end_date":"","owner_id":"9","priority_default":"0","priority_start":"0","priority_end":"3","url":{"board":"https:\/\/pm.zhdk.ch\/?controller=BoardViewController&action=show&project_id=1","calendar":"https:\/\/pm.zhdk.ch\/?controller=CalendarController&action=show&project_id=1","list":"https:\/\/pm.zhdk.ch\/?controller=TaskListController&action=show&project_id=1"}}],"id":2134420212}

Imported board has no users

I ran your import script and it worked on the first try! There's a lot of fiddly bits and passwords to get in the right place but your instructions are very easy to follow and complete. That was awesome.

The imported board has no members, not even the "userId" member that I used to import comments, however, and so only my admin accounts seem to be able to see it. If I paste the address of the board (https://localhost/?controller=BoardViewController&action=show&project_id=2) in to a session with a non-admin user logged in, I get "Access Forbidden".

How do I bootstrap this board? Do I need to go edit the database by hand?

Documentation: How to get the Trello Token ?

Hi there,

I tried to use your import script, and everything was going well after cloning and installing the dependencies, but launching the request just returned me a HTTP Code 401 : Unauthorized.
I got it was due to a mismatch between the Trello Application Secret and Token.

So I was wondering how could I get the Trello Token associated with my user ? It is really not clear in their documentation, and your seems outdated (no references to "Click here to request a token to be used in the example" in the https://trello.com/app-key page)

If you have any answers, it would really help me,

PS: I cannot stand OAuth 1.0... Have been implementing a few authorizations process based on it in the last year and it is always painful ;-)

HTTP request failed! HTTP/1.1 426 Upgrade Required

Currently fails with

$ php import.php "<url>" $token $trellokey $trellotoken $trelloboard 1
PHP Warning:  file_get_contents(https://trello.com/1/boards/...): failed to open stream: HTTP request failed! HTTP/1.1 426 Upgrade Required
 in /home/dtantsur/Soft/kanboard-import-trello/import.php on line 43
Unable to parse JSON response, is it valid? Syntax error

Applying the switch to cURL from https://stackoverflow.com/questions/64059867/php-http-426-file-get-contents-vs-curl fixes the issue.

autoload.php error

Hi,

when I try to run the import.php script it stops with the following error message:

PHP Fatal error: require_once(): Failed opening required '/root/kanboard-import-trello-master/vendor/autoload.php' (include_path='.:/usr/share/php:/usr/share/pear') in /root/kanboard-import-trello-master/import.php on line 2

What am I doing wrong ?

Bye, Torsten...

Empty lists

Hi,
I can execute the script and it creates a project in Kanboard with the same name that the board in Trello and with the same lists, but these lists are empty.
When I execute the script everything seems ok. There is no errors, and the prompt says "Adding cards", but no cards are created in Kanboard.

Can you help me?
Thanks!

Allow skipping certificate validation

It seems that the JSON-RPC client always tries to verify its peer, at least the way it's used right now. This makes it impossible to import into a Kanboard instance that has an invalid or self-signed certificate.

It should be possible to skip certificate validation during import, or to specify some additional valid certs so that the self-signed one can be supplied.

/fguillot/json-rpc error

Getting the following error. I have triple verified all api keys/tokens. It seem there may be a update to /fguillot/json-rpc?

PHP Fatal error: Uncaught exception 'JsonRPC\ConnectionFailureException' with message 'Unable to establish a connection' in /root/kanboard-import-trello/vendor/fguillot/json-rpc/src/JsonRPC/Client.php:309
Stack trace:
#0 /root/kanboard-import-trello/vendor/fguillot/json-rpc/src/JsonRPC/Client.php(201): JsonRPC\Client->doRequest(Array)
#1 /root/kanboard-import-trello/vendor/fguillot/json-rpc/src/JsonRPC/Client.php(137): JsonRPC\Client->execute('getAllProjects', Array)
#2 /root/kanboard-import-trello/import.php(58): JsonRPC\Client->__call('getAllProjects', Array)
#3 /root/kanboard-import-trello/import.php(58): JsonRPC\Client->getAllProjects()
#4 {main}

thrown in /root/kanboard-import-trello/vendor/fguillot/json-rpc/src/JsonRPC/Client.php on line 309

If kanboard is on a commercial host

Hello,

I tried to migrate the tool to be used with a commercially managed host. I can pass php-code to there, but can only call it via the browser. So I modified the code to use $_GET (See code at the end). According to my tracing it all works well up to the point where the RCP comes into play (After line 88 of the amended code). And if I look at the RPC, it doesn't fit what is given in the description (call: php import.php http://server/jsonrpc.php apitoken trellokey trellotoken trelloboard userid). There is no jsonrpc.php in the project at github. I am new to this kind of stuff so I might be dumb, although I am into SW for a long time in the embedded world. There was an autoload include at the beginning of import.php, which (obviously) didn't work.
The code I use is attached. Is it possible to create a document how to use and adapt the script and the rpc lib to be used for kanboard located on a managed host?

Yours,

Ulrich Hauser-Ehninger

null, JSON_ERROR_DEPTH => 'Maximum stack depth exceeded', JSON_ERROR_STATE_MISMATCH => 'Underflow or the modes mismatch', JSON_ERROR_CTRL_CHAR => 'Unexpected control character found', JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON', JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded' ); $error = json_last_error(); return array_key_exists($error, $errors) ? $errors[$error] : "Unknown error ({$error})"; } } /**-------- END FUNCTIONS --------------**/ echo ("Passed line: " . **LINE** . PHP_EOL); if (""==$_GET["server"]) {/\* assume we were NIT called via http*/ echo ("I was called directly\n"); if ($argc !== 6 && $argc !== 7) { echo 'Use this small tool to import your Trello JSON export into your kanboard, using it JSON-RPC interface.' . PHP_EOL; printf('Usage: php %s http://server/jsonrpc.php apitoken trellokey trellotoken trelloboard [userId]%s', $argv[0], PHP_EOL); echo 'To get the Trello key and token, login to Trello and go to https://trello.com/app-key'.PHP_EOL; echo 'The user id is optional. If you provide it, comments will be created with that userId.'.PHP_EOL; die; } $server = $argv[1]; $token = $argv[2]; $trellokey = $argv[3]; $trellotoken = $argv[4]; $trelloboard = $argv[5]; $userId = null; if (isset($argv[6])) { $userId = $argv[6]; } } else {/_assume we were called via http"_/ echo ("I was called via https\n"); if (!isset ($_GET["server"])) die ("Parameter 'server' not present"); $server = $_GET["server"]; if (!isset ($_GET["token"])) die ("Parameter 'token' not present"); $token = $_GET["token"]; if (!isset ($_GET["trellokey"])) die ("Parameter 'trellokey' not present"); $trellokey = $_GET["trellokey"]; if (!isset ($_GET["trellotoken"])) die ("Parameter 'trellotoken' not present"); $trellotoken = $_GET["trellotoken"]; if (!isset ($_GET["trelloboard"])) die ("Parameter 'trelloboard' not present"); $trelloboard = $_GET["trelloboard"]; $userId = null; if (isset($_GET["userid"])) { $userId = $_GET["userid"];; } } echo ("I will import from: ". $trelloboard . PHP_EOL); $fileName="https://trello.com/1/boards/".$trelloboard."?key=".$trellokey."&token=".$trellotoken; echo ("reading file: ".$fileName. PHP_EOL); $jsonString = file_get_contents("https://trello.com/1/boards/".$trelloboard."?key=".$trellokey."&token=".$trellotoken); echo ("Passed line: " . **LINE** . PHP_EOL); $trelloObj = json_decode($jsonString); echo ("Passed line: " . **LINE** . PHP_EOL); if (empty($trelloObj)) { printf($jsonString); printf('Unable to parse JSON response, is it valid? %s', json_last_error_msg()); die(1); } echo ("Passed line: " . **LINE** . PHP_EOL); //initialize the client $client = new Client($server); echo ("Passed line: " . **LINE** . PHP_EOL); $client->authentication('jsonrpc', $token); echo ("Passed line: " . **LINE** . PHP_EOL); //verify that we can connect $projects = null; try { $projects = $client->getAllProjects(); } catch(RuntimeException $e) { $projects = null; //explicitly set it to null, to trigger an error } echo ("Passed line: " . **LINE** . PHP_EOL); $users = $client->getAllUsers(); foreach ($users as $user) { if ($user['username'] == $userId || $userId == null) { $userId = $user['id']; } } echo ("Passed line: " . **LINE** . PHP_EOL); if (!is_array($projects)) { echo 'Unable to fetch the list of projects, is the server url / token correct?' . PHP_EOL; die(1); } echo ("Passed line: " . **LINE** . PHP_EOL); //variables $trelloLists = array(); $trelloLabels = array(); //we will store all label names, but not add them immediately, only when used $trelloAttachments = array(); //create the project echo 'Creating project.' . PHP_EOL; $projectId = $client->createProject($trelloObj->name); $counter=0; while (empty($projectId)) { $projectId = $client->createProject($trelloObj->name.$counter++); // die("We could not create the project, perhaps it already exists?".PHP_EOL); } echo ("Passed line: " . **LINE** . PHP_EOL); //remove the columns created by default $columns = $client->getColumns($projectId); foreach ($columns as $column) { $client->removeColumn($column['id']); } echo ("Passed line: " . **LINE** . PHP_EOL); //set the public/private status of the project if ($trelloObj->prefs->permissionLevel=="private") { echo "project is private".PHP_EOL; // $client->updateProject(array('id' => $projectId, 'is_public' => false)); } echo ("Passed line: " . **LINE** . PHP_EOL); # will only get lists that are not archived $jsonString = file_get_contents("https://trello.com/1/boards/".$trelloboard."/lists?key=".$trellokey."&token=".$trellotoken); $trelloObjLists = json_decode($jsonString); echo ("Passed line: " . **LINE** . PHP_EOL); //add the lists echo 'Adding lists.' . PHP_EOL; foreach ($trelloObjLists as $list) { if ($list->closed) { // ignore archived lists continue; } echo 'Creating list '.$list->name.PHP_EOL; $columnId = $client->addColumn($projectId, $list->name); $trelloLists[$list->id] = $columnId; ``` //add each card echo 'Adding cards.' . PHP_EOL; $query="https://trello.com/1/lists/".$list->id."?key=".$trellokey."&token=".$trellotoken."&cards=open&card_fields=all&card_checklists=all&members=all&member_fields=all&membersInvited=all&checklists=all&organization=true&organization_fields=all&fields=all"; // &actions=commentCard,copyCommentCard&card_attachments=true"; $jsonCards = file_get_contents($query); $trelloObjCards = json_decode($jsonCards); foreach ($trelloObjCards->cards as $card) { addCard($projectId, $columnId, $card); } ``` } echo 'All done!' . PHP_EOL; die; function addCard($projectId, $columnId, $card) { global $trellokey; global $trellotoken; global $trelloLabels; global $client; global $userId; ``` if ($card->closed) { // ignore archived cards return; } $dueDate = $card->due !== null ? date('Y-m-d', strtotime($card->due)) : null; //Kanboard supports only one category, take the first one of the Trello labels $colorId = null; $categoryId = null; if (count($card->labels) > 0) { $trelloLabel = $card->labels[0]; $colorId = $trelloLabel->color; if (isset($trelloLabels[$trelloLabel->id])) { $categoryId = $trelloLabels[$trelloLabel->id]; } else { $categoryId = $client->createCategory($projectId, $trelloLabel->name); $trelloLabels[$trelloLabel->id] = $categoryId; } } $params = array( 'title' => $card->name, 'project_id' => $projectId, 'column_id' => $columnId ); if ($card->desc !== null) { $params['description'] = $card->desc; } if ($dueDate !== null) { $params['date_due'] = $dueDate; } if ($colorId !== null) { $params['color_id'] = $colorId; } if ($categoryId !== null) { $params['category_id'] = $categoryId; } if ($userId !== null) { $params['owner_id'] = $userId; } $taskId = $client->createTask($params); if ($card->badges->comments > 0) { $jsonString = file_get_contents("https://trello.com/1/cards/". $card->shortLink."/actions?key=".$trellokey."&token=".$trellotoken."&filter=all"); $cardDetails = json_decode($jsonString); addComments($cardDetails, $taskId); } if ($card->badges->checkItems > 0) { $jsonString = file_get_contents("https://trello.com/1/cards/". $card->shortLink."/checklists?key=".$trellokey."&token=".$trellotoken); $cardDetails = json_decode($jsonString); addCheckItems($cardDetails, $taskId); } if ($card->badges->attachments > 0) { $jsonString = file_get_contents("https://trello.com/1/cards/". $card->shortLink."/attachments?key=".$trellokey."&token=".$trellotoken); $cardDetails = json_decode($jsonString); addAttachments($card, $cardDetails, $taskId); } ``` } //download attachments function addAttachments($card, $cardDetails, $taskId) { global $userId; global $client; ``` foreach ($cardDetails as $attachment) { if ($attachment->isUpload) { $filename = $taskId . '_' . $attachment->name; printf('Downloading attachment for task %s to %s.%s', $card->name, $filename, PHP_EOL); $fpOut = fopen($filename, 'w'); //Here is the file we are downloading, replace spaces with %20 $ch = curl_init($attachment->url); curl_setopt($ch, CURLOPT_TIMEOUT, 50); //give curl the file pointer so that it can write to it curl_setopt($ch, CURLOPT_FILE, $fpOut); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); $data = curl_exec($ch);//get curl response if ($data === false) { printf('Unable to download attachment: %s%s', curl_error($ch), PHP_EOL); } //done curl_close($ch); // add a comment about the file $text = "There was a file link in Trello, the file was called ".$attachment->name."\n\nSee local file ".$filename."\n\nThe original link is [".$attachment->name."](".$attachment->url.")"; $client->createComment(array('task_id' => $taskId, 'user_id' => $userId, 'content' => $text)); } else { // just an url, add a comment $text = $attachment->url; $client->createComment(array('task_id' => $taskId, 'user_id' => $userId, 'content' => $text)); } } ``` } //add checklists as subtasks function addCheckItems($cardDetails, $taskId) { global $userId; global $client; $statusTodo = 0; $statusDone = 2; ``` foreach ($cardDetails as $checkList) { foreach ($checkList->checkItems as $checkItem) { $title = $checkList->name . ' - ' . $checkItem->name; $status = $checkItem->state === 'incomplete' ? $statusTodo : $statusDone; $client->createSubtask(array('task_id' => $taskId, 'title' => $title, 'status' => $status)); } } ``` } function addComments($cardDetails, $taskId) { global $userId; global $client; foreach ($cardDetails as $comment) { if ($comment->type === 'commentCard') { $text = $comment->data->text; $client->createComment(array('task_id' => $taskId, 'user_id' => $userId, 'content' => $text)); } } } ?>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.