diff --git a/Chatdown/.chatrc b/Chatdown/.chatrc new file mode 100644 index 00000000..31eca967 --- /dev/null +++ b/Chatdown/.chatrc @@ -0,0 +1,4 @@ +{ + "in": "sample.chat", + "out": "sample.transcript" +} \ No newline at end of file diff --git a/ChatMD/docs/readme.md b/Chatdown/docs/readme.md similarity index 100% rename from ChatMD/docs/readme.md rename to Chatdown/docs/readme.md diff --git a/Chatdown/lib/activity.js b/Chatdown/lib/activity.js new file mode 100644 index 00000000..c1186324 --- /dev/null +++ b/Chatdown/lib/activity.js @@ -0,0 +1,30 @@ +const ActivityType = require('./activityType'); + +class Activity { + /** + * + * @property {Attachment[]} attachments + */ + + /** + * @property text + */ + + /** + * @property timestamp + */ + + /** + * @property id + */ + + /** + * @property type + */ + + constructor({ attachments = [], text = '', timestamp = '', id = -1, type = ActivityType.Message } = {}) { + Object.assign(this, { attachments, text, timestamp, id, type }); + } +} + +module.exports = Activity; diff --git a/Chatdown/lib/activityField.js b/Chatdown/lib/activityField.js new file mode 100644 index 00000000..de3b04e4 --- /dev/null +++ b/Chatdown/lib/activityField.js @@ -0,0 +1,3 @@ +module.exports = { + Attachments: 'attachments' +}; \ No newline at end of file diff --git a/Chatdown/lib/activityType.js b/Chatdown/lib/activityType.js new file mode 100644 index 00000000..778f0d2d --- /dev/null +++ b/Chatdown/lib/activityType.js @@ -0,0 +1,16 @@ +module.exports = { + Message: 'message', + ContactRelationUpdate: 'contactRelationUpdate', + ConversationUpdate: 'conversationUpdate', + Typing: 'typing', + Ping: 'ping', + EndOfConversation: 'endOfConversation', + Event: 'event', + Invoke: 'invoke', + DeleteUserData: 'deleteUserData', + MessageUpdate: 'messageUpdate', + MessageDelete: 'messageDelete', + InstallationUpdate: 'installationUpdate', + MessageReaction: 'messageReaction', + Suggestion: 'suggestion', +}; \ No newline at end of file diff --git a/Chatdown/lib/attachment.js b/Chatdown/lib/attachment.js new file mode 100644 index 00000000..b7c6c134 --- /dev/null +++ b/Chatdown/lib/attachment.js @@ -0,0 +1,7 @@ +class Attachment { + constructor({ contentType = '', contentUrl = '', content = null }) { + Object.assign(this, { contentType, contentUrl, content }); + } +} + +module.exports = Attachment; \ No newline at end of file diff --git a/Chatdown/lib/chatdown.js b/Chatdown/lib/chatdown.js new file mode 100644 index 00000000..a978b2b9 --- /dev/null +++ b/Chatdown/lib/chatdown.js @@ -0,0 +1,61 @@ +const Activity = require('./activity'); +const ActivityType = require('./activityType'); +const ActivityField = require('./activityField'); +const Attachment = require('./attachment'); + +module.exports = async function readFileContents(fileContents) { + const activities = []; + let currentActivity; + let aggregate = ''; + let len = fileContents.length; + let i = 0; + for (; i < len; i++) { + const char = fileContents.charAt(i); + if (char !== '[') { + aggregate += char; + continue; + } + if (aggregate && currentActivity) { + currentActivity.message = aggregate.trim(); + aggregate = ''; + } + const { index, activity } = await readActivity(++i, fileContents); + i = index; + currentActivity = activity; + activities.push(activity); + } + return activities; +}; + +async function readActivity(index, fileContents) { + let len = fileContents.length; + let activity = new Activity(); + let aggregate = ''; + for (; index < len; index++) { + const char = fileContents.charAt(index); + if (char === ']') { + break; + } + aggregate += char; + } + const [ typeOrField, ...rest ] = aggregate.split(':'); + const type = ActivityType[ typeOrField ]; + if (type) { + activity.type = type; + } + + const field = ActivityField[ typeOrField ]; + if (field === ActivityField.Attachments) { + let [ contentType, content ] = rest; + if (contentType.includes('json')) { + try { + content = JSON.parse(content); + } catch (e) { + throw new Error(`The attachment contentType was "${contentType}" but the contents failed to parse correctly.`); + } + } + activity.attachments.push(new Attachment({ contentType, content })); + } + + return { index, activity }; +} diff --git a/ChatMD/src/readme.md b/Chatdown/lib/readme.md similarity index 100% rename from ChatMD/src/readme.md rename to Chatdown/lib/readme.md diff --git a/Chatdown/package-lock.json b/Chatdown/package-lock.json new file mode 100644 index 00000000..3c6a36ed --- /dev/null +++ b/Chatdown/package-lock.json @@ -0,0 +1,62 @@ +{ + "name": "chatdown", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", + "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "5.2.0" + } + }, + "color-convert": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", + "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "supports-color": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", + "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "requires": { + "has-flag": "3.0.0" + } + } + } +} diff --git a/Chatdown/package.json b/Chatdown/package.json new file mode 100644 index 00000000..3fe8c35a --- /dev/null +++ b/Chatdown/package.json @@ -0,0 +1,29 @@ +{ + "name": "chatdown", + "version": "0.0.1", + "description": "Tool for parsing chat files and outputting replayable activities", + "main": "lib/chatdown.js", + "directories": { + "doc": "docs" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Microsoft/botbuilder-tools.git" + }, + "author": "Microsoft", + "license": "ISC", + "bugs": { + "url": "https://github.com/Microsoft/botbuilder-tools/issues" + }, + "homepage": "https://github.com/Microsoft/botbuilder-tools#readme", + "dependencies": { + "chalk": "^2.3.1", + "minimist": "^1.2.0" + }, + "bin": { + "chatdown": "./bin/chatdown.js" + } +} diff --git a/ChatMD/readme.md b/Chatdown/readme.md similarity index 100% rename from ChatMD/readme.md rename to Chatdown/readme.md diff --git a/Chatdown/sample.chat b/Chatdown/sample.chat new file mode 100644 index 00000000..590491c9 --- /dev/null +++ b/Chatdown/sample.chat @@ -0,0 +1,16 @@ +[Message:LulaBot] Hi! + +[Message:Joe] yo! +[Typing:LulaBot:3000] +[Message:LulaBot] Greetings! +What would you like to do? +* update - You can update your account +* List - You can list your data +* help - you can get help + +[Message:Joe] I need help + +[Message:LulaBot] +Here you go. + +[Attachments:LulaBot:content-type/json:{"imageUrl":"http://someimageurl"}]