Browse files

GitHub for Mac: Throw-away commit.

  • Loading branch information...
0 parents commit 0240456a41e20a3ef19e6cd246faa7e21d044bb3 @chadlung committed Feb 19, 2012
BIN .DS_Store
Binary file not shown.
1 .idea/.name
@@ -0,0 +1 @@
+JSONHopper
9 .idea/JSONHopper.iml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+ <component name="NewModuleRootManager">
+ <content url="file://$MODULE_DIR$" />
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module>
+
5 .idea/encodings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
+</project>
+
11 .idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,11 @@
+<component name="InspectionProjectProfileManager">
+ <profile version="1.0" is_locked="false">
+ <option name="myName" value="Project Default" />
+ <option name="myLocal" value="false" />
+ <inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
+ <option name="processCode" value="true" />
+ <option name="processLiterals" value="true" />
+ <option name="processComments" value="true" />
+ </inspection_tool>
+ </profile>
+</component>
7 .idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,7 @@
+<component name="InspectionProjectProfileManager">
+ <settings>
+ <option name="PROJECT_PROFILE" value="Project Default" />
+ <option name="USE_PROJECT_PROFILE" value="true" />
+ <version value="1.0" />
+ </settings>
+</component>
25 .idea/misc.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ProjectResources">
+ <default-html-doctype>http://www.w3.org/1999/xhtml</default-html-doctype>
+ </component>
+ <component name="ProjectRootManager" version="2" />
+ <component name="SvnConfiguration" maxAnnotateRevisions="500">
+ <option name="USER" value="" />
+ <option name="PASSWORD" value="" />
+ <option name="mySSHConnectionTimeout" value="30000" />
+ <option name="mySSHReadTimeout" value="30000" />
+ <option name="LAST_MERGED_REVISION" />
+ <option name="MERGE_DRY_RUN" value="false" />
+ <option name="MERGE_DIFF_USE_ANCESTRY" value="true" />
+ <option name="UPDATE_LOCK_ON_DEMAND" value="false" />
+ <option name="IGNORE_SPACES_IN_MERGE" value="false" />
+ <option name="DETECT_NESTED_COPIES" value="true" />
+ <option name="CHECK_NESTED_FOR_QUICK_MERGE" value="false" />
+ <option name="IGNORE_SPACES_IN_ANNOTATE" value="true" />
+ <option name="SHOW_MERGE_SOURCES_IN_ANNOTATE" value="true" />
+ <option name="FORCE_UPDATE" value="false" />
+ <myIsUseDefaultProxy>false</myIsUseDefaultProxy>
+ </component>
+</project>
+
9 .idea/modules.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ProjectModuleManager">
+ <modules>
+ <module fileurl="file://$PROJECT_DIR$/.idea/JSONHopper.iml" filepath="$PROJECT_DIR$/.idea/JSONHopper.iml" />
+ </modules>
+ </component>
+</project>
+
5 .idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+<component name="DependencyValidationManager">
+ <state>
+ <option name="SKIP_IMPORT_STATEMENTS" value="false" />
+ </state>
+</component>
7 .idea/vcs.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="VcsDirectoryMappings">
+ <mapping directory="" vcs="" />
+ </component>
+</project>
+
354 .idea/workspace.xml
@@ -0,0 +1,354 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ChangeListManager">
+ <list default="true" id="4b582a6a-ace2-4380-bb81-56ab37450f9a" name="Default" comment="" />
+ <ignored path="JSONHopper.iws" />
+ <ignored path=".idea/workspace.xml" />
+ <option name="TRACKING_ENABLED" value="true" />
+ <option name="SHOW_DIALOG" value="false" />
+ <option name="HIGHLIGHT_CONFLICTS" value="true" />
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+ <option name="LAST_RESOLUTION" value="IGNORE" />
+ </component>
+ <component name="ChangesViewManager" flattened_view="true" show_ignored="false" />
+ <component name="CreatePatchCommitExecutor">
+ <option name="PATCH_PATH" value="" />
+ </component>
+ <component name="DaemonCodeAnalyzer">
+ <disable_hints />
+ </component>
+ <component name="FavoritesManager">
+ <favorites_list name="JSONHopper" />
+ </component>
+ <component name="FileEditorManager">
+ <leaf>
+ <file leaf-file-name="entry.js" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/models/entry.js">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="12" column="13" selection-start="405" selection-end="405" vertical-scroll-proportion="0.0">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="package.json" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/package.json">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="2" column="42" selection-start="73" selection-end="73" vertical-scroll-proportion="0.0">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="app.js" pinned="false" current="true" current-in-tab="true">
+ <entry file="file://$PROJECT_DIR$/app.js">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="75" column="42" selection-start="3081" selection-end="3081" vertical-scroll-proportion="0.7129032">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="config.js" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/config.js">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="10" column="20" selection-start="199" selection-end="199" vertical-scroll-proportion="0.0">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="entry-tests.js" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/tests/entry-tests.js">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="0" column="33" selection-start="33" selection-end="33" vertical-scroll-proportion="0.0">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ </leaf>
+ </component>
+ <component name="FindManager">
+ <FindUsagesManager>
+ <setting name="OPEN_NEW_TAB" value="false" />
+ </FindUsagesManager>
+ </component>
+ <component name="Git.Settings">
+ <option name="CHECKOUT_INCLUDE_TAGS" value="false" />
+ <option name="UPDATE_CHANGES_POLICY" value="STASH" />
+ <option name="LINE_SEPARATORS_CONVERSION" value="ASK" />
+ </component>
+ <component name="IdeDocumentHistory">
+ <option name="changedFiles">
+ <list>
+ <option value="$PROJECT_DIR$/jsonEntry.js" />
+ <option value="$PROJECT_DIR$/jsonEntryModel.js" />
+ <option value="$PROJECT_DIR$/models/jsonEntry.js" />
+ <option value="$PROJECT_DIR$/models/Entry.js" />
+ <option value="$PROJECT_DIR$/config.js" />
+ <option value="$PROJECT_DIR$/tests/entry-tests.js" />
+ <option value="$PROJECT_DIR$/models/entry.js" />
+ <option value="$PROJECT_DIR$/package.json" />
+ <option value="$PROJECT_DIR$/app.js" />
+ </list>
+ </option>
+ </component>
+ <component name="ProjectFrameBounds">
+ <option name="y" value="22" />
+ <option name="width" value="1920" />
+ <option name="height" value="967" />
+ </component>
+ <component name="ProjectInspectionProfilesVisibleTreeState">
+ <entry key="Project Default">
+ <profile-state>
+ <expanded-state>
+ <State>
+ <id />
+ </State>
+ <State>
+ <id>JavaScript</id>
+ </State>
+ </expanded-state>
+ <selected-state>
+ <State>
+ <id>Spelling</id>
+ </State>
+ </selected-state>
+ </profile-state>
+ </entry>
+ </component>
+ <component name="ProjectLevelVcsManager" settingsEditedManually="false">
+ <OptionsSetting value="true" id="Add" />
+ <OptionsSetting value="true" id="Remove" />
+ <OptionsSetting value="true" id="Checkout" />
+ <OptionsSetting value="true" id="Update" />
+ <OptionsSetting value="true" id="Status" />
+ <OptionsSetting value="true" id="Edit" />
+ <ConfirmationsSetting value="0" id="Add" />
+ <ConfirmationsSetting value="0" id="Remove" />
+ </component>
+ <component name="ProjectReloadState">
+ <option name="STATE" value="0" />
+ </component>
+ <component name="ProjectView">
+ <navigator currentView="ProjectPane" proportions="" version="1" splitterProportion="0.5">
+ <flattenPackages />
+ <showMembers />
+ <showModules />
+ <showLibraryContents ProjectPane="false" />
+ <hideEmptyPackages />
+ <abbreviatePackageNames />
+ <autoscrollToSource />
+ <autoscrollFromSource />
+ <sortByType />
+ </navigator>
+ <panes>
+ <pane id="Scope" />
+ <pane id="ProjectPane">
+ <subPane>
+ <PATH>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="JSONHopper" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="jsonfeedserver" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ </PATH>
+ </subPane>
+ </pane>
+ </panes>
+ </component>
+ <component name="PropertiesComponent">
+ <property name="options.splitter.main.proportions" value="0.3" />
+ <property name="WebServerToolWindowFactoryState" value="false" />
+ <property name="recentsLimit" value="5" />
+ <property name="options.lastSelected" value="preferences.sourceCode.JavaScript" />
+ <property name="last_opened_file_path" value="$PROJECT_DIR$/../Project1" />
+ <property name="FullScreen" value="false" />
+ <property name="options.splitter.details.proportions" value="0.2" />
+ <property name="options.searchVisible" value="true" />
+ </component>
+ <component name="RunManager" selected="Node JS.app.js">
+ <configuration default="false" name="entry-tests" type="NodeJSConfigurationType" factoryName="Node JS" temporary="true" path-to-node="/usr/local/bin/node" path-to-js-file="$PROJECT_DIR$/tests/entry-tests.js" coffeescript-run="false">
+ <RunnerSettings RunnerId="NodeJS.run" />
+ <ConfigurationWrapper RunnerId="NodeJS.run" />
+ <method />
+ </configuration>
+ <configuration default="false" name="app" type="NodeJSConfigurationType" factoryName="Node JS" temporary="true" path-to-node="/usr/local/bin/node" path-to-js-file="$PROJECT_DIR$/app.js" coffeescript-run="false">
+ <RunnerSettings RunnerId="NodeJS.run" />
+ <ConfigurationWrapper RunnerId="NodeJS.run" />
+ <method />
+ </configuration>
+ <configuration default="false" name="app.js" type="NodeJSConfigurationType" factoryName="Node JS" temporary="true" path-to-node="/usr/local/bin/node" path-to-js-file="$PROJECT_DIR$/app.js" coffeescript-run="false">
+ <RunnerSettings RunnerId="NodeJS.run" />
+ <ConfigurationWrapper RunnerId="NodeJS.run" />
+ <method />
+ </configuration>
+ <configuration default="true" type="NodeJSConfigurationType" factoryName="Node JS" coffeescript-run="false">
+ <method>
+ <option name="PhingTarget" enabled="false" />
+ </method>
+ </configuration>
+ <configuration default="true" type="JavascriptDebugSession" factoryName="Local">
+ <JSDebuggerConfigurationSettings>
+ <option name="engineId" value="embedded" />
+ <option name="fileUrl" />
+ </JSDebuggerConfigurationSettings>
+ <method />
+ </configuration>
+ <list size="3">
+ <item index="0" class="java.lang.String" itemvalue="Node JS.entry-tests" />
+ <item index="1" class="java.lang.String" itemvalue="Node JS.app" />
+ <item index="2" class="java.lang.String" itemvalue="Node JS.app.js" />
+ </list>
+ </component>
+ <component name="ShelveChangesManager" show_recycled="false" />
+ <component name="TaskManager">
+ <task active="true" id="Default" summary="Default task">
+ <changelist id="4b582a6a-ace2-4380-bb81-56ab37450f9a" name="Default" comment="" />
+ <created>1325529722349</created>
+ <updated>1325529722349</updated>
+ </task>
+ <servers />
+ </component>
+ <component name="TodoView" selected-index="0">
+ <todo-panel id="selected-file">
+ <are-packages-shown value="false" />
+ <are-modules-shown value="false" />
+ <flatten-packages value="false" />
+ <is-autoscroll-to-source value="false" />
+ </todo-panel>
+ <todo-panel id="all">
+ <are-packages-shown value="false" />
+ <are-modules-shown value="false" />
+ <flatten-packages value="false" />
+ <is-autoscroll-to-source value="false" />
+ </todo-panel>
+ <todo-panel id="default-changelist">
+ <are-packages-shown value="false" />
+ <are-modules-shown value="false" />
+ <flatten-packages value="false" />
+ <is-autoscroll-to-source value="false" />
+ </todo-panel>
+ </component>
+ <component name="ToolWindowManager">
+ <frame x="0" y="22" width="1920" height="967" extended-state="0" />
+ <editor active="true" />
+ <layout>
+ <window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
+ <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.20990565" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
+ <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="true" content_ui="tabs" />
+ <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.16341592" sideWeight="0.7629717" order="0" side_tool="false" content_ui="tabs" />
+ <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+ <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
+ <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" />
+ <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.2370283" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
+ <window_info id="JsTestDriver Server" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
+ <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
+ <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
+ <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+ <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+ <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+ <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+ <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
+ <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
+ </layout>
+ </component>
+ <component name="VcsContentAnnotationSettings">
+ <option name="myLimit" value="2678400000" />
+ </component>
+ <component name="VcsManagerConfiguration">
+ <option name="OFFER_MOVE_TO_ANOTHER_CHANGELIST_ON_PARTIAL_COMMIT" value="true" />
+ <option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="true" />
+ <option name="CHECK_NEW_TODO" value="true" />
+ <option name="myTodoPanelSettings">
+ <value>
+ <are-packages-shown value="false" />
+ <are-modules-shown value="false" />
+ <flatten-packages value="false" />
+ <is-autoscroll-to-source value="false" />
+ </value>
+ </option>
+ <option name="PERFORM_UPDATE_IN_BACKGROUND" value="true" />
+ <option name="PERFORM_COMMIT_IN_BACKGROUND" value="true" />
+ <option name="PERFORM_EDIT_IN_BACKGROUND" value="true" />
+ <option name="PERFORM_CHECKOUT_IN_BACKGROUND" value="true" />
+ <option name="PERFORM_ADD_REMOVE_IN_BACKGROUND" value="true" />
+ <option name="PERFORM_ROLLBACK_IN_BACKGROUND" value="false" />
+ <option name="CHECK_LOCALLY_CHANGED_CONFLICTS_IN_BACKGROUND" value="false" />
+ <option name="ENABLE_BACKGROUND_PROCESSES" value="false" />
+ <option name="CHANGED_ON_SERVER_INTERVAL" value="60" />
+ <option name="SHOW_ONLY_CHANGED_IN_SELECTION_DIFF" value="true" />
+ <option name="CHECK_COMMIT_MESSAGE_SPELLING" value="true" />
+ <option name="DEFAULT_PATCH_EXTENSION" value="patch" />
+ <option name="SHORT_DIFF_HORISONTALLY" value="true" />
+ <option name="SHORT_DIFF_EXTRA_LINES" value="2" />
+ <option name="SOFT_WRAPS_IN_SHORT_DIFF" value="true" />
+ <option name="INCLUDE_TEXT_INTO_PATCH" value="false" />
+ <option name="INCLUDE_TEXT_INTO_SHELF" value="false" />
+ <option name="CREATE_PATCH_EXPAND_DETAILS_DEFAULT" value="true" />
+ <option name="FORCE_NON_EMPTY_COMMENT" value="false" />
+ <option name="LAST_COMMIT_MESSAGE" />
+ <option name="MAKE_NEW_CHANGELIST_ACTIVE" value="true" />
+ <option name="OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT" value="false" />
+ <option name="CHECK_FILES_UP_TO_DATE_BEFORE_COMMIT" value="false" />
+ <option name="REFORMAT_BEFORE_PROJECT_COMMIT" value="false" />
+ <option name="REFORMAT_BEFORE_FILE_COMMIT" value="false" />
+ <option name="FILE_HISTORY_DIALOG_COMMENTS_SPLITTER_PROPORTION" value="0.8" />
+ <option name="FILE_HISTORY_DIALOG_SPLITTER_PROPORTION" value="0.5" />
+ <option name="ACTIVE_VCS_NAME" />
+ <option name="UPDATE_GROUP_BY_PACKAGES" value="false" />
+ <option name="UPDATE_GROUP_BY_CHANGELIST" value="false" />
+ <option name="SHOW_FILE_HISTORY_AS_TREE" value="false" />
+ <option name="FILE_HISTORY_SPLITTER_PROPORTION" value="0.6" />
+ </component>
+ <component name="XDebuggerManager">
+ <breakpoint-manager />
+ </component>
+ <component name="editorHistoryManager">
+ <entry file="file://$PROJECT_DIR$/../Project1/myapp.js">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="37" column="11" selection-start="1032" selection-end="1032" vertical-scroll-proportion="0.76613885" />
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/tests/entry-tests.js">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="0" column="33" selection-start="33" selection-end="33" vertical-scroll-proportion="0.0">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/package.json">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="2" column="42" selection-start="73" selection-end="73" vertical-scroll-proportion="0.0">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/models/entry.js">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="12" column="13" selection-start="405" selection-end="405" vertical-scroll-proportion="0.0">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/config.js">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="10" column="20" selection-start="199" selection-end="199" vertical-scroll-proportion="0.0">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/app.js">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="75" column="42" selection-start="3081" selection-end="3081" vertical-scroll-proportion="0.7129032">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </component>
+</project>
+
95 app.js
@@ -0,0 +1,95 @@
+// ./mongod --dbpath ~/mongodb-2.0.1/data/db/
+
+var express = require('express')
+ ,app = express.createServer(
+ express.bodyParser()
+ , express.responseTime()
+ , express.logger())
+ , util = require('util')
+ , httpStatus = require('http-status')
+ , config = require(__dirname + '/config')
+ , Entry = require(__dirname + '/models/entry.js')
+ , INVALID_JSON_ERROR = 'Only valid JSON is supported via HTTP POST';
+
+var entry = new Entry(config.mongodb.connectionUrl);
+
+app.post('/*', function(req, res){
+ if(req.is('application/json')) {
+ entry.save({body: req.body,
+ feed: req.params[0],
+ selfHref: config.server.domain + req.params[0]},
+ function(error, returnedEntry) {
+ if(error) {
+ res.send(error.message, httpStatus.INTERNAL_SERVER_ERROR);
+ } else {
+ res.send(returnedEntry, httpStatus.CREATED);
+ }
+ });
+ } else {
+ res.send(INVALID_JSON_ERROR, httpStatus.UNSUPPORTED_MEDIA_TYPE);
+ }
+});
+
+app.get('/*', function(req, res){
+ if(req.query.id != undefined) {
+ entry.getId({ id: req.query.id }, function (error, returnedEntry) {
+ if(error) {
+ res.send(error.message, httpStatus.INTERNAL_SERVER_ERROR);
+ } else {
+ if(returnedEntry != undefined) {
+ res.json(returnedEntry);
+ } else {
+ res.send('The id specified was not found', httpStatus.NOT_FOUND);
+ }
+ }
+ });
+ } else {
+ var feedLimit = (req.query.limit == undefined) ? config.feed.limit : req.query.limit
+ , skip = (req.query.skip == undefined) ? config.feed.skip : req.query.skip;
+ entry.getFeed({ feed: req.params[0], limit: feedLimit, skip: skip }, function (error, returnedEntries) {
+ if(error) {
+ res.send(error.message, httpStatus.INTERNAL_SERVER_ERROR);
+ } else {
+ var entriesJSON = {}
+ , firstEntryID
+ , lastEntryID
+ , entryCount = 0;
+
+ for(var entry in returnedEntries){
+ if(entryCount === 0) {
+ firstEntryID = returnedEntries[entry].id;
+ }
+ // If there is only one entry the weak ETag should be the same unique id seperated by a dash
+ lastEntryID = returnedEntries[entry].id;
+
+ var tempJSONObj = {};
+ // TODO: This will "de-stringify" the body, there should be a better way to do this...
+ tempJSONObj.body = JSON.parse(returnedEntries[entry].body);
+ tempJSONObj.selfHref = returnedEntries[entry].selfHref;
+ tempJSONObj.entryDate = returnedEntries[entry].entryDate;
+ entriesJSON[returnedEntries[entry].id] = tempJSONObj;
+ entryCount++;
+ }
+
+ if(entryCount > 0) {
+ res.header('ETag', 'W/"' + firstEntryID + '-' + lastEntryID + '"');
+ res.json(entriesJSON);
+ } else {
+ res.send('The requested feed does not exist', httpStatus.NOT_FOUND);
+ }
+ }
+ });
+ }
+});
+
+app.configure(function(){
+ app.use(express.bodyParser());
+ app.use(express.responseTime());
+
+ app.use(function(err, req, res, next){
+ res.send(INVALID_JSON_ERROR, httpStatus.UNSUPPORTED_MEDIA_TYPE);
+ });
+});
+
+app.listen(config.server.port);
+console.log('Listening on port ' + config.server.port);
15 config.js
@@ -0,0 +1,15 @@
+var config = {};
+
+config.server = {};
+config.feed = {};
+config.mongodb = {};
+
+config.server.port = 8080;
+config.server.domain = 'http://localhost:8080/';
+
+config.feed.limit = 25;
+config.feed.skip = 0;
+
+config.mongodb.connectionUrl = 'mongodb://localhost/jsonfeedserver';
+
+module.exports = config;
35 models/entry.js
@@ -0,0 +1,35 @@
+var mongoose = require('mongoose')
+ , Schema = mongoose.Schema;
+
+var JSONEntry = new Schema({
+ body: { type: String },
+ feed: { type: String, index: true },
+ selfHref: { type: String, index: false },
+ entryDate: { type: Date, default: Date.now }
+});
+var jsonEntryModel = mongoose.model('JSONEntry', JSONEntry);
+
+var entry = exports = module.exports = function(connectionURL) {
+ mongoose.connect(connectionURL);
+};
+
+entry.prototype.save = function(incomingJsonEntry, callback) {
+ var jsonEntry = new jsonEntryModel();
+ jsonEntry.body = JSON.stringify(incomingJsonEntry.body);
+ jsonEntry.feed = incomingJsonEntry.feed;
+ jsonEntry.selfHref = incomingJsonEntry.selfHref + '?id=' + jsonEntry._id;
+ callback(jsonEntry.save(), jsonEntry);
+}
+
+entry.prototype.getId = function(obj, callback) {
+ jsonEntryModel.findOne({ _id: obj.id }, callback);
+}
+
+entry.prototype.getFeed = function(obj, callback) {
+ var query = jsonEntryModel.find({});
+ query.where('feed', obj.feed).desc('entryDate').skip(obj.skip).limit(obj.limit).run(callback);
+}
+
+entry.prototype.disconnect = function() {
+ mongoose.disconnect();
+}
22 package.json
@@ -0,0 +1,22 @@
+{
+ "name": "jsonfeedserver"
+ , "description": "JSON Feed Server - A JSON feed store"
+ , "version": "0.0.1"
+ , "author": "Chad Lung <chad.lung@gmail.com>"
+ , "homepage": "https://github.com/chadlung/jsonfeedserver"
+ , "keywords": ["json", "server"]
+ , "engines": { "node": ">= 0.6.7" }
+ , "dependencies": {
+ "express": ">=2.4.5"
+ , "http-status": ">=0.1.1"
+ , "mongoose": ">=2.4.10"
+ }
+ , "devDependencies": {
+ "nodeunit": ">=0.7.3"
+ }
+ , "repository": {
+ "type": "git"
+ , "url": "git://github.com/chadlung/jsonfeedserver.git"
+ }
+ , "main" : "app.js"
+}
0 readme.md
No changes.
33 tests/entry-tests.js
@@ -0,0 +1,33 @@
+// To run from the 'tests' folder: ../node_modules/nodeunit/bin/nodeunit entry-tests.js
+
+var assert = require('assert')
+ , Entry = require('../models/entry.js')
+ , nodeUnit = require('../node_modules/nodeunit')
+ , util = require('util')
+ , TEST_OBJECT = {property1:1, property2:2}
+ , TEST_BODY = JSON.stringify(TEST_OBJECT)
+ , TEST_FEED = 'namespace/feed/'
+ , TEST_SELF_HREF = 'http://localhost:8080/namespace/feed/';
+
+var entry = new Entry('mongodb://localhost/jsonfeedserverTest');
+
+exports.saveEntry = function(test){
+ test.expect(2);
+
+ entry.save({body: TEST_BODY,
+ feed: TEST_FEED,
+ selfHref: TEST_SELF_HREF},
+ function(error, returnedEntry) {
+ console.log(util.inspect(returnedEntry));
+ assert.ok(!error);
+ test.equal(returnedEntry.feed, TEST_FEED, 'Failure: Feed should match original data');
+ test.equal(returnedEntry.selfHref, TEST_SELF_HREF + '?id=' + returnedEntry._id, 'Failure: Self Href should match original data');
+ console.log(util.inspect(entry));
+ // HACK: For some reason the connection will hang, pulled this code from here:
+ // https://github.com/LearnBoost/mongoose/issues/330
+ setTimeout( function () {
+ entry.disconnect();
+ }, 1000);
+ test.done();
+ });
+};

0 comments on commit 0240456

Please sign in to comment.