clean up packages names

This commit is contained in:
Sacha Greif 2016-11-29 11:35:20 +09:00
parent a6836a5db8
commit d0c72c98f1
155 changed files with 750 additions and 3161 deletions

View file

@ -26,7 +26,6 @@ nova:users # user management and permissions
# nova:api
# nova:rss
# nova:subscribe
# nova:cloudinary
############ Customizable Packages ############

View file

@ -1 +0,0 @@
.build*

View file

@ -1,58 +0,0 @@
aldeed:autoform@5.1.2
aldeed:simple-schema@1.3.2
base64@1.0.3
binary-heap@1.0.3
blaze@2.1.2
blaze-tools@1.0.3
boilerplate-generator@1.0.3
callback-hook@1.0.3
cfs:http-methods@0.0.28
check@1.0.5
coffeescript@1.0.6
ddp@1.1.0
deps@1.0.7
ejson@1.0.6
geojson-utils@1.0.3
html-tools@1.0.4
htmljs@1.0.4
id-map@1.0.3
iron:controller@1.0.7
iron:core@1.0.7
iron:dynamic-template@1.0.7
iron:layout@1.0.7
iron:location@1.0.7
iron:middleware-stack@1.0.7
iron:router@1.0.7
iron:url@1.0.7
jquery@1.11.3_2
json@1.0.3
livedata@1.0.13
logging@1.0.7
meteor@1.1.6
minifiers@1.1.5
minimongo@1.0.8
momentjs:moment@2.8.4
mongo@1.1.0
observe-sequence@1.0.6
ordered-dict@1.0.3
random@1.0.3
reactive-dict@1.1.0
reactive-var@1.0.5
retry@1.0.3
routepolicy@1.0.5
session@1.1.0
spacebars@1.0.6
spacebars-compiler@1.0.6
tap:i18n@1.4.1
nova:i18n@0.1.0
nova:invites@0.1.0
nova:lib@0.3.1
nova:messages@0.1.0
nova:settings@0.1.0
nova:users@0.1.0
templating@1.1.1
tracker@1.0.7
ui@1.0.6
underscore@1.0.3
webapp@1.2.0
webapp-hashing@1.0.3

View file

@ -1 +0,0 @@
Telescope invites package, used internally.

View file

@ -1,2 +0,0 @@
{
}

View file

@ -1,2 +0,0 @@
{
}

View file

@ -1,3 +0,0 @@
{
"translation_key" : "Proměnná překladu"
}

View file

@ -1,2 +0,0 @@
{
}

View file

@ -1,3 +0,0 @@
{
"translation_key" : "translation string"
}

View file

@ -1,2 +0,0 @@
{
}

View file

@ -1,3 +0,0 @@
{
"translation_key" : "translation string"
}

View file

@ -1,2 +0,0 @@
{
}

View file

@ -1,3 +0,0 @@
{
"translation_key" : "tõlkimise string"
}

View file

@ -1,3 +0,0 @@
{
"translation_key" : "رشته ترجمه"
}

View file

@ -1,3 +0,0 @@
{
"translation_key" : "traduire une chaîne de caractères"
}

View file

@ -1,2 +0,0 @@
{
}

View file

@ -1,3 +0,0 @@
{
"translation_key" : "translation string"
}

View file

@ -1,3 +0,0 @@
{
"translation_key" : "translation string"
}

View file

@ -1,2 +0,0 @@
{
}

View file

@ -1,3 +0,0 @@
{
"translation_key" : "аударма текст"
}

View file

@ -1,3 +0,0 @@
{
"translation_key" : "번역 문자열"
}

View file

@ -1,2 +0,0 @@
{
}

View file

@ -1,2 +0,0 @@
{
}

View file

@ -1,2 +0,0 @@
{
}

View file

@ -1,3 +0,0 @@
{
"translation_key" : "translation string"
}

View file

@ -1,3 +0,0 @@
{
"translation_key" : "chave de tradução"
}

View file

@ -1,2 +0,0 @@
{
}

View file

@ -1,2 +0,0 @@
{
}

View file

@ -1,2 +0,0 @@
{
}

View file

@ -1,3 +0,0 @@
{
"translation_key" : "preveden niz"
}

View file

@ -1,3 +0,0 @@
{
"translation_key" : "översättningstext"
}

View file

@ -1,2 +0,0 @@
{
}

View file

@ -1,2 +0,0 @@
{
}

View file

@ -1,3 +0,0 @@
{
"translation_key" : "çeviri dizgisi"
}

View file

@ -1,2 +0,0 @@
{
}

View file

@ -1,3 +0,0 @@
{
"translation_key" : "translation string"
}

View file

@ -1,41 +0,0 @@
<template name="user_invites">
<div class="grid-small grid-block dialog admin">
<h3>Invites</h3>
{{#if canCurrentUserInvite}}
{{#autoForm schema=invitesSchema id="inviteForm" class="form-block" type="method" meteormethod="inviteUser"}}
<h3>Invite someone</h3>
<div class="control-group">
<label>Email</label>
<div class="controls">
{{> afFieldInput name="invitedUserEmail"}}
</div>
</div>
<div class="form-actions">
{{#if afFieldIsInvalid name="invitedUserEmail"}}
This is not a valid email
{{/if}}
<input type="submit" class="button btn btn-primary" value="Invite" />
</div>
{{/autoForm}}
{{/if}}
<table>
<thead>
<tr>
<td>Email</td>
<td>Accepted</td>
</tr>
</thead>
<tbody>
{{#each invites}}
<tr>
<td>{{invitedUserEmail}}</td>
<td>{{#if accepted}}{{{icon "voted"}}}{{/if}}</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</template>

View file

@ -1,62 +0,0 @@
Template.user_invites.created = function () {
var user = this.data;
var instance = this;
instance.invites = new ReactiveVar({});
Meteor.autorun(function () {
Telescope.subsManager.subscribe('invites', user._id);
var invites = Invites.find({invitingUserId: user._id});
instance.invites.set(invites);
});
};
Template.user_invites.helpers({
canCurrentUserInvite: function () {
var currentUser = Meteor.user();
return currentUser && (Users.isAdmin(currentUser) || currentUser.telescope.inviteCount > 0 && Users.can.invite(currentUser));
},
invitesLeft: function () {
var currentUser = Meteor.user();
return (currentUser && !(Users.isAdmin(currentUser))) ? (currentUser.telescope.inviteCount - currentUser.telescope.invitedCount) : 0
},
invitesSchema: function () {
// expose schema for Invites (used by AutoForm)
return Invites.simpleSchema();
},
invites: function () {
return Template.instance().invites.get();
}
});
var scrollUp = function(){
Deps.afterFlush(function() {
var element = $('.grid > .error');
$('html, body').animate({scrollTop: element.offset().top});
});
};
AutoForm.hooks({
inviteForm: {
onSuccess: function(operation, result) {
Messages.clearSeen();
if(result && result.newUser){
Messages.flash('An invite has been sent out. Thank you!', "success");
} else {
Messages.flash('Thank you!', "info");
}
scrollUp();
},
onError: function(operation, error) {
Messages.clearSeen();
if(error && error.reason){
Messages.flash(error.reason, "error");
scrollUp();
}
}
}
});

View file

@ -1,130 +0,0 @@
var InviteSchema = new SimpleSchema({
_id: {
type: String,
optional: true
},
invitingUserId: {
type: String,
optional: true
},
invitedUserEmail: {
type: String,
regEx: SimpleSchema.RegEx.Email
},
accepted: {
type: Boolean,
optional: true
}
});
Invites = new Meteor.Collection("invites");
Invites.attachSchema(InviteSchema);
Users.addField([
/**
A count of the user's remaining invites
*/
{
fieldName: "telescope.inviteCount",
fieldSchema: {
type: Number,
optional: true
}
},
/**
A count of how many users have been invited by the user
*/
{
fieldName: "telescope.invitedCount",
fieldSchema: {
type: Number,
optional: true
}
},
/**
Whether the user is invited or not
*/
{
fieldName: "telescope.isInvited",
fieldSchema: {
type: Boolean,
publish: true,
optional: true,
insertableIf: Users.isAdmin,
editableIf: Users.isAdmin,
autoform: {
omit: true
}
}
},
/**
The _id of the user who invited the current user
*/
{
fieldName: "telescope.invitedBy",
fieldSchema: {
type: String,
optional: true,
autoform: {
omit: true
}
}
},
/**
The name of the user who invited the current user
*/
{
fieldName: "telescope.invitedByName",
fieldSchema: {
type: String,
optional: true,
autoform: {
omit: true
}
}
}
]);
// invites are managed through Meteor method
Invites.deny({
insert: function(){ return true; },
update: function(){ return true; },
remove: function(){ return true; }
});
Telescope.modules.add("profileEdit", {
template: 'user_invites',
order: 2
});
function setStartingInvites (user) {
// give new users a few invites (default to 3)
user.telescope.inviteCount = Settings.get('startInvitesCount', 3);
return user;
}
Telescope.callbacks.add("onCreateUser", setStartingInvites);
// on profile completion, check if the new user has been invited
// if so set her status accordingly and update invitation info
function checkIfInvited (user) {
var invite = Invites.findOne({ invitedUserEmail : Users.getEmail(user) });
if(invite){
var invitedBy = Meteor.users.findOne({ _id : invite.invitingUserId });
Users.update(user._id, { $set: {
"telescope.isInvited": true,
"telescope.invitedBy": invitedBy._id,
"telescope.invitedByName": Users.getDisplayName(invitedBy)
}});
Invites.update(invite._id, {$set : {
accepted : true
}});
}
}
Telescope.callbacks.add("profileCompletedAsync", checkIfInvited);

View file

@ -1,89 +0,0 @@
Meteor.methods({
inviteUser: function(invitation){
check(invitation, Match.Any);
// invite user returns the following hash
// { newUser : true|false }
// newUser is true if the person being invited is not on the site yet
// invitation can either contain userId or an email address :
// { invitedUserEmail : 'bob@gmail.com' } or { userId : 'user-id' }
check(invitation, Match.OneOf(
{ invitedUserEmail : String },
{ userId : String }
));
var user = invitation.invitedUserEmail ?
Meteor.users.findOne({ emails : { $elemMatch: { address: invitation.invitedUserEmail } } }) :
Meteor.users.findOne({ _id : invitation.userId });
var userEmail = invitation.invitedUserEmail ? invitation.invitedUserEmail :Users.getEmail(user);
var currentUser = Meteor.user();
var currentUserIsAdmin = Users.isAdmin(currentUser);
var currentUserCanInvite = currentUserIsAdmin || (currentUser.telescope.inviteCount > 0 && Users.can.invite(currentUser));
// check if the person is already invited
if(user && Users.is.invited(user)){
throw new Meteor.Error(403, "This person is already invited.");
} else {
if (!currentUserCanInvite){
throw new Meteor.Error(701, "You can't invite this user, sorry.");
}
// don't allow duplicate multiple invite for the same person
var existingInvite = Invites.findOne({ invitedUserEmail : userEmail });
if (existingInvite) {
throw new Meteor.Error(403, "Somebody has already invited this person.");
}
// create an invite
// consider invite accepted if the invited person has an account already
Invites.insert({
invitingUserId: Meteor.userId(),
invitedUserEmail: userEmail,
accepted: typeof user !== "undefined"
});
// update invinting user
Meteor.users.update(Meteor.userId(), {$inc:{"telescope.inviteCount": -1, "telescope.invitedCount": 1}});
if(user){
// update invited user
Meteor.users.update(user._id, {
$set: {
"telescope.isInvited": true,
"telescope.invitedBy": Meteor.userId(),
"telescope.invitedByName": Users.getDisplayName(currentUser)
}
});
}
var communityName = Settings.get('title','Telescope'),
emailSubject = 'You are invited to try '+communityName,
emailProperties = {
newUser : typeof user === 'undefined',
communityName : communityName,
actionLink : user ? Telescope.utils.getSigninUrl() : Telescope.utils.getSignupUrl(),
invitedBy : Users.getDisplayName(currentUser),
profileUrl : Users.getProfileUrl(currentUser),
siteUrl: Settings.get("siteUrl")
};
Meteor.setTimeout(function () {
NovaEmail.buildAndSend(userEmail, emailSubject, 'emailInvite', emailProperties);
}, 1);
}
return {
newUser : typeof user === 'undefined'
};
},
unInviteUser: function (userId) {
Meteor.users.update(userId, {$set: {"telescope.isInvited": false}});
}
});

View file

@ -1,4 +0,0 @@
Meteor.publish('invites', function (userId) {
var invites = Invites.find({invitingUserId: userId});
return (this.userId === userId || Users.isAdminById(this.userId)) ? invites : [];
});

View file

@ -1,39 +0,0 @@
import NovaEmail from 'meteor/nova:email';
// Invitation email
Picker.route('/email/invite-existing-user/:id?', function(params, req, res, next) {
var html;
var invitingUser = typeof params.id === "undefined" ? Meteor.users.findOne() : Meteor.users.findOne(params.id);
var communityName = Settings.get('title','Telescope'),
emailProperties = {
newUser : false,
communityName : communityName,
actionLink : Telescope.utils.getSigninUrl(),
invitedBy : Users.getDisplayName(invitingUser),
profileUrl : Users.getProfileUrl(invitingUser)
};
html = NovaEmail.getTemplate('emailInvite')(emailProperties);
res.end(NovaEmail.buildTemplate(html));
});
// Invitation email
Picker.route('/email/invite-new-user/:id?', function(params, req, res, next) {
var html;
var invitingUser = typeof params.id === "undefined" ? Meteor.users.findOne() : Meteor.users.findOne(params.id);
var communityName = Settings.get('title','Telescope'),
emailProperties = {
newUser : true,
communityName : communityName,
actionLink : Telescope.utils.getSignupUrl(),
invitedBy : Users.getDisplayName(invitingUser),
profileUrl : Users.getProfileUrl(invitingUser)
};
html = NovaEmail.getTemplate('emailInvite')(emailProperties);
res.end(NovaEmail.buildTemplate(html));
});

View file

@ -1,5 +0,0 @@
import NovaEmail from 'meteor/nova:email';
NovaEmail.addTemplates({
emailInvite: Assets.getText("lib/server/templates/emailInvite.handlebars")
});

View file

@ -1,11 +0,0 @@
<span class="heading">
<a href="{{profileUrl}}">{{invitedBy}}</a> invited you to join {{communityName}}
</span><br><br>
{{#if newUser}}
<a href="{{siteUrl}}{{actionLink}}">Join {{communityName}}</a>
{{else}}
<a href="{{siteUrl}}{{actionLink}}">Sign in to {{communityName}}</a>
{{/if}}
<br><br>

View file

@ -1,5 +0,0 @@
{
"translation_function_name": "__",
"helper_name": "_",
"namespace": "project"
}

View file

@ -1,82 +0,0 @@
Package.describe({
name: "invites",
summary: "Telescope invites package",
version: "0.27.2-nova",
git: "https://github.com/TelescopeJS/telescope-invites.git"
});
Npm.depends({
// NPM package dependencies
});
Package.onUse(function (api) {
api.versionsFrom("METEOR@1.0");
// --------------------------- 1. Meteor packages dependencies ---------------------------
// automatic (let the package specify where it's needed)
api.use(['nova:core@0.27.2-nova']);
// client
api.use([
'jquery',
'underscore',
'templating'
], ['client']);
// server
api.use([
//
], ['server']);
// ---------------------------------- 2. Files to include ----------------------------------
// i18n config (must come first)
api.addFiles([
'package-tap.i18n'
], ['client', 'server']);
// both
api.addFiles([
'lib/invites.js'
], ['client', 'server']);
// client
api.addFiles([
'lib/client/templates/user_invites.html',
'lib/client/templates/user_invites.js'
], ['client']);
// server
api.addAssets([
'lib/server/templates/emailInvite.handlebars'
], ['server']);
api.addFiles([
'lib/server/invites.js',
'lib/server/publications.js',
'lib/server/routes.js',
'lib/server/templates.js'
], ['server']);
// i18n languages (must come last)
var languages = ["ar", "bg", "cs", "da", "de", "el", "en", "es", "et", "fr", "hu", "id", "it", "ja", "kk", "ko", "nl", "pl", "pt-BR", "ro", "ru", "sl", "sv", "th", "tr", "vi", "zh-CN"];
var languagesPaths = languages.map(function (language) {
return "i18n/"+language+".i18n.json";
});
api.addFiles(languagesPaths, ["client", "server"]);
// -------------------------------- 3. Variables to export --------------------------------
api.export("Invites");
});

View file

@ -1,235 +0,0 @@
{
"dependencies": [
[
"aldeed:autoform",
"4.2.0"
],
[
"aldeed:simple-schema",
"1.2.0"
],
[
"application-configuration",
"1.0.3"
],
[
"base64",
"1.0.1"
],
[
"binary-heap",
"1.0.1"
],
[
"blaze",
"2.0.3"
],
[
"blaze-tools",
"1.0.1"
],
[
"boilerplate-generator",
"1.0.1"
],
[
"callback-hook",
"1.0.1"
],
[
"check",
"1.0.2"
],
[
"coffeescript",
"1.0.4"
],
[
"ddp",
"1.0.12"
],
[
"deps",
"1.0.5"
],
[
"ejson",
"1.0.4"
],
[
"follower-livedata",
"1.0.2"
],
[
"geojson-utils",
"1.0.1"
],
[
"html-tools",
"1.0.2"
],
[
"htmljs",
"1.0.2"
],
[
"id-map",
"1.0.1"
],
[
"iron:controller",
"1.0.3"
],
[
"iron:core",
"1.0.4"
],
[
"iron:dynamic-template",
"1.0.5"
],
[
"iron:layout",
"1.0.5"
],
[
"iron:location",
"1.0.4"
],
[
"iron:middleware-stack",
"1.0.3"
],
[
"iron:router",
"1.0.3"
],
[
"iron:url",
"1.0.4"
],
[
"jquery",
"1.0.1"
],
[
"json",
"1.0.1"
],
[
"livedata",
"1.0.11"
],
[
"logging",
"1.0.5"
],
[
"meteor",
"1.1.3"
],
[
"minifiers",
"1.1.2"
],
[
"minimongo",
"1.0.5"
],
[
"mongo",
"1.0.9"
],
[
"mrt:moment",
"2.8.1"
],
[
"observe-sequence",
"1.0.3"
],
[
"ordered-dict",
"1.0.1"
],
[
"random",
"1.0.1"
],
[
"reactive-dict",
"1.0.4"
],
[
"reactive-var",
"1.0.3"
],
[
"retry",
"1.0.1"
],
[
"routepolicy",
"1.0.2"
],
[
"session",
"1.0.4"
],
[
"spacebars",
"1.0.3"
],
[
"spacebars-compiler",
"1.0.3"
],
[
"tap:http-methods",
"0.0.23"
],
[
"tap:i18n",
"1.2.1"
],
[
"telescope-base",
"0.0.0"
],
[
"nova:i18n",
"0.0.0"
],
[
"telescope-lib",
"0.2.9"
],
[
"templating",
"1.0.9"
],
[
"tracker",
"1.0.3"
],
[
"ui",
"1.0.4"
],
[
"underscore",
"1.0.1"
],
[
"webapp",
"1.1.4"
],
[
"webapp-hashing",
"1.0.1"
]
],
"pluginDependencies": [],
"toolVersion": "meteor-tool@1.0.36",
"format": "1.0"
}

View file

@ -1 +0,0 @@
Telescope migrations package, used internally.

View file

@ -1,740 +0,0 @@
import marked from 'marked';
import Posts from "meteor/nova:posts";
import Comments from "meteor/nova:comments";
import Categories from "meteor/nova:categories";
import Events from "meteor/nova:events";
import Users from "meteor/nova:users";
// TODO: switch over to Tom's migration package.
// database migrations
// http://stackoverflow.com/questions/10365496/meteor-how-to-perform-database-migrations
Migrations = new Meteor.Collection('migrations');
Meteor.startup(function () {
allMigrations = Object.keys(migrationsList);
_.each(allMigrations, function(migrationName){
runMigration(migrationName);
});
});
Meteor.methods({
removeMigration: function (name) {
check(name, String);
if (Users.isAdmin(Meteor.user())) {
console.log('// removing migration: ' + name);
Migrations.remove({name: name});
}
}
});
// wrapper function for all migrations
var runMigration = function (migrationName) {
var migration = Migrations.findOne({name: migrationName});
if (migration){
if(typeof migration.finishedAt === 'undefined'){
// if migration exists but hasn't finished, remove it and start fresh
console.log('!!! Found incomplete migration "'+migrationName+'", removing and running again.');
Migrations.remove({name: migrationName});
}else{
// do nothing
// console.log('Migration "'+migrationName+'" already exists, doing nothing.')
return;
}
}
console.log("//----------------------------------------------------------------------//");
console.log("//------------// Starting "+migrationName+" Migration //-----------//");
console.log("//----------------------------------------------------------------------//");
Migrations.insert({name: migrationName, startedAt: new Date(), completed: false});
// execute migration function
var itemsAffected = migrationsList[migrationName]() || 0;
Migrations.update({name: migrationName}, {$set: {finishedAt: new Date(), completed: true, itemsAffected: itemsAffected}});
console.log("//----------------------------------------------------------------------//");
console.log("//------------// Ending "+migrationName+" Migration //-----------//");
console.log("//----------------------------------------------------------------------//");
};
var migrationsList = {
updatePostStatus: function () {
var i = 0;
Posts.find({status: {$exists : false}}).forEach(function (post) {
i++;
Posts.update(post._id, {$set: {status: 2}});
console.log("---------------------");
console.log("Post: "+post.title);
console.log("Updating status to approved");
});
return i;
},
updateCategories: function () {
if (typeof Categories === "undefined" || Categories === null) return;
var i = 0;
Categories.find({slug: {$exists : false}}).forEach(function (category) {
i++;
var slug = Telescope.utils.slugify(category.name);
Categories.update(category._id, {$set: {slug: slug}});
console.log("---------------------");
console.log("Category: "+category.name);
console.log("Updating category with new slug: "+slug);
});
return i;
},
updatePostCategories: function () {
if (typeof Categories === "undefined" || Categories === null) return;
var i = 0;
Posts.find().forEach(function (post) {
i++;
var oldCategories = post.categories;
var newCategories = [];
var category = {};
var updating = false; // by default, assume we're not going to do anything
// iterate over the post.categories array
// if the post has no categories then nothing will happen
_.each(oldCategories, function(value){
// make sure the categories are strings
if((typeof value === "string") && (category = Categories.findOne({name: value}))){
// if value is a string, then look for the matching category object
// and if it exists push it to the newCategories array
updating = true; // we're updating at least one category for this post
newCategories.push(category);
}else{
// if category A) is already an object, or B) it's a string but a matching category object doesn't exist
// just keep the current value
newCategories.push(value);
}
});
if(updating){
// update categories property on post
Posts.update(post._id, {$set: {categories: newCategories}});
}
// START CONSOLE LOGS
console.log("---------------------");
console.log("Post: "+post.title);
if(updating){
console.log(oldCategories.length+" categories: "+oldCategories);
console.log("Updating categories array to: ");
console.log(newCategories);
}else{
console.log("No updates");
}
// END CONSOLE LOGS
});
return i;
},
updateUserProfiles: function () {
var i = 0;
var allUsers = Meteor.users.find();
console.log('> Found '+allUsers.count()+' users.\n');
allUsers.forEach(function(user){
i++;
console.log('> Updating user '+user._id+' ('+user.username+')');
var properties = {};
properties.telescope = {};
// update user slug
if(Users.getUserName(user))
properties.slug = Telescope.utils.slugify(Users.getUserName(user));
// update user isAdmin flag
if(typeof user.isAdmin === 'undefined')
properties.isAdmin = false;
// update postCount
var postsByUser = Posts.find({userId: user._id});
properties.telescope.postCount = postsByUser.count();
// update commentCount
var commentsByUser = Comments.find({userId: user._id});
properties.telescope.commentCount = commentsByUser.count();
Meteor.users.update(user._id, {$set:properties});
});
return i;
},
resetUpvotesDownvotes: function () {
var i = 0;
Posts.find().forEach(function (post) {
i++;
var upvotes = 0,
downvotes = 0;
console.log("Post: "+post.title);
if(post.upvoters){
upvotes = post.upvoters.length;
console.log("Found "+upvotes+" upvotes.");
}
if(post.downvoters){
downvotes = post.downvoters.length;
console.log("Found "+downvotes+" downvotes.");
}
Posts.update(post._id, {$set: {upvotes: upvotes, downvotes: downvotes}});
console.log("---------------------");
});
return i;
},
resetCommentsUpvotesDownvotes: function () {
var i = 0;
Comments.find().forEach(function (comment) {
i++;
var upvotes = 0,
downvotes = 0;
console.log("Comment: "+comment._id);
if(comment.upvoters){
upvotes = comment.upvoters.length;
console.log("Found "+upvotes+" upvotes.");
}
if(comment.downvoters){
downvotes = comment.downvoters.length;
console.log("Found "+downvotes+" downvotes.");
}
Comments.update(comment._id, {$set: {upvotes: upvotes, downvotes: downvotes}});
console.log("---------------------");
});
return i;
},
headlineToTitle: function () {
var i = 0;
Posts.find({title: {$exists : false}}).forEach(function (post) {
i++;
console.log("Post: "+post.headline+" "+post.title);
Posts.update(post._id, { $rename: { 'headline': 'title'}}, {multi: true, validate: false});
console.log("---------------------");
});
return i;
},
commentsSubmittedToCreatedAt: function () {
var i = 0;
Comments.find({createdAt: {$exists: false}}).forEach(function (comment) {
i++;
console.log("Comment: "+comment._id);
Comments.update(comment._id, { $rename: { 'submitted': 'createdAt'}}, {multi: true, validate: false});
console.log("---------------------");
});
return i;
},
commentsPostToPostId: function () {
var i = 0;
Comments.find({postId: {$exists : false}}).forEach(function (comment) {
i++;
console.log("Comment: "+comment._id);
Comments.update(comment._id, { $rename: { 'post': 'postId'}}, {multi: true, validate: false});
console.log("---------------------");
});
return i;
},
createdAtSubmittedToDate: function () {
var i = 0;
Posts.find().forEach(function (post) {
if(typeof post.submitted === "number" || typeof post.createdAt === "number"){
i++;
console.log("Posts: "+post.title);
var createdAt = new Date(post.createdAt);
var submitted = new Date(post.submitted);
console.log(createdAt);
Posts.update(post._id, { $set: { 'createdAt': createdAt, submitted: submitted}}, {multi: true, validate: false});
console.log("---------------------");
}
});
return i;
},
commentsCreatedAtToDate: function () {
var i = 0;
Comments.find().forEach(function (comment) {
if(typeof comment.createdAt === "number"){
i++;
console.log("Comment: "+comment._id);
var createdAt = new Date(comment.createdAt);
console.log(createdAt);
Comments.update(comment._id, { $set: { 'createdAt': createdAt}}, {multi: true, validate: false});
console.log("---------------------");
}
});
return i;
},
submittedToPostedAt: function () {
var i = 0;
Posts.find({submitted: {$exists : true}, postedAt: {$exists : false}}).forEach(function (post) {
i++;
console.log("Post: "+post._id);
Posts.update(post._id, { $rename: { 'submitted': 'postedAt'}}, {multi: true, validate: false});
console.log("---------------------");
});
return i;
},
addPostedAtToComments: function () {
var i = 0;
Comments.find({postedAt: {$exists : false}}).forEach(function (comment) {
i++;
console.log("Comment: "+comment._id);
Comments.update(comment._id, { $set: { 'postedAt': comment.createdAt}}, {multi: true, validate: false});
console.log("---------------------");
});
return i;
},
parentToParentCommentId: function () {
var i = 0;
Comments.find({parent: {$exists: true}, parentCommentId: {$exists : false}}).forEach(function (comment) {
i++;
console.log("Comment: "+comment._id);
Comments.update(comment._id, { $set: { 'parentCommentId': comment.parent}}, {multi: true, validate: false});
console.log("---------------------");
});
return i;
},
addLastCommentedAt: function () {
var i = 0;
Posts.find({$and: [
{$or: [{comments: {$gt: 0}}, {commentCount: {$gt: 0}}]},
{lastCommentedAt: {$exists : false}}
]}).forEach(function (post) {
i++;
console.log("Post: "+post._id);
var postComments = Comments.find({$or: [{postId: post._id}, {post: post._id}]}, {sort: {postedAt: -1}}).fetch();
var lastComment;
if (_.isEmpty(postComments)) {
console.log('postComments from post '+post._id+' is empty. Skipping.');
return;
}
lastComment = postComments[0];
Posts.update(post._id, { $set: { lastCommentedAt: lastComment.postedAt}}, {multi: false, validate: false});
console.log("---------------------");
});
return i;
},
commentsToCommentCount: function () {
var i = 0;
Posts.find({comments: {$exists : true}, commentCount: {$exists : false}}).forEach(function (post) {
i++;
console.log("Post: "+post._id);
Posts.update(post._id, { $set: { 'commentCount': post.comments}, $unset: { 'comments': ''}}, {multi: true, validate: false});
console.log("---------------------");
});
return i;
},
addCommentersToPosts: function () {
var i = 0;
Comments.find().forEach(function (comment) {
i++;
console.log("Comment: "+comment._id);
console.log("Post: "+comment.postId);
Posts.update(comment.postId, { $addToSet: { 'commenters': comment.userId}}, {multi: true, validate: false});
console.log("---------------------");
});
return i;
},
moveVotesFromProfile: function () {
var i = 0;
Meteor.users.find().forEach(function (user) {
i++;
console.log("User: "+user._id);
Meteor.users.update(user._id, {
$rename: {
'profile.upvotedPosts': 'telescope.upvotedPosts',
'profile.downvotedPosts': 'telescope.downvotedPosts',
'profile.upvotedComments': 'telescope.upvotedComments',
'profile.downvotedComments': 'telescope.downvotedComments'
}
}, {multi: true, validate: false});
console.log("---------------------");
});
return i;
},
addHTMLBody: function () {
var i = 0;
Posts.find({body: {$exists : true}}).forEach(function (post) {
i++;
var htmlBody = Telescope.utils.sanitize(marked(post.body));
console.log("Post: "+post._id);
Posts.update(post._id, { $set: { 'htmlBody': htmlBody}}, {multi: true, validate: false});
console.log("---------------------");
});
return i;
},
addHTMLComment: function () {
var i = 0;
Comments.find({body: {$exists : true}}).forEach(function (comment) {
i++;
var htmlBody = Telescope.utils.sanitize(marked(comment.body));
console.log("Comment: "+comment._id);
Comments.update(comment._id, { $set: { 'htmlBody': htmlBody}}, {multi: true, validate: false});
console.log("---------------------");
});
return i;
},
clicksToClickCount: function () {
var i = 0;
Posts.find({"clicks": {$exists: true}, "clickCount": {$exists : false}}).forEach(function (post) {
i++;
console.log("Post: " + post._id);
Posts.update(post._id, { $set: { 'clickCount': post.clicks}, $unset: { 'clicks': ''}}, {multi: true, validate: false});
console.log("---------------------");
});
return i;
},
commentsCountToCommentCount: function () {
var i = 0;
Posts.find({"commentCount": {$exists : false}}).forEach(function (post) {
i++;
console.log("Post: " + post._id);
Posts.update({_id: post._id}, { $set: { 'commentCount': post.commentsCount}, $unset: {'commentsCount': ""}}, {multi: true, validate: false});
console.log("---------------------");
});
return i;
},
userDataCommentsCountToCommentCount: function(){
var i = 0;
Meteor.users.find({'commentCount': {$exists: false}}).forEach(function(user){
i++;
var commentCount = Comments.find({userId: user._id}).count();
console.log("User: " + user._id);
Meteor.users.update(user._id, {$set: { telescope : {'commentCount': commentCount}}});
console.log("---------------------");
});
return i;
},
clicksToClickCountForRealThisTime: function () { // since both fields might be co-existing, add to clickCount instead of overwriting it
var i = 0;
Posts.find({'clicks': {$exists: true}}).forEach(function (post) {
i++;
console.log("Post: " + post._id);
Posts.update(post._id, { $inc: { 'clickCount': post.clicks}, $unset: {'clicks': ""}}, {multi: true, validate: false});
console.log("---------------------");
});
return i;
},
normalizeCategories: function () {
var i = 0;
Posts.find({'categories': {$exists: true}}).forEach(function (post) {
i++;
console.log("Post: " + post._id);
var justCategoryIds = post.categories.map(function (category){
return category._id;
});
Posts.update(post._id, {$set: {categories: justCategoryIds, oldCategories: post.categories}}, {multi: true, validate: false});
console.log("---------------------");
});
return i;
},
cleanUpStickyProperty: function () {
var i = 0;
Posts.find({'sticky': {$exists: false}}).forEach(function (post) {
i++;
console.log("Post: " + post._id);
Posts.update(post._id, {$set: {sticky: false}}, {multi: true, validate: false});
console.log("---------------------");
});
return i;
},
show0112ReleaseNotes: function () {
var i = 0;
// if this is the 0.11.2 update, the first run event will not exist yet.
// if that's the case, make sure to still show release notes
if (!Events.findOne({name: 'firstRun'})) {
Releases.update({number:'0.11.2'}, {$set: {read:false}});
}
return i;
},
removeThumbnailHTTP: function () {
var i = 0;
Posts.find({thumbnailUrl: {$exists : true}}).forEach(function (post) {
i++;
var newThumbnailUrl = post.thumbnailUrl.replace("http:", "");
console.log("Post: "+post._id);
Posts.update(post._id, { $set: { 'thumbnailUrl': newThumbnailUrl}}, {multi: true, validate: false});
console.log("---------------------");
});
return i;
},
updateUserNames: function () {
var i = 0;
var allUsers = Meteor.users.find({username: {$exists: true}, profile: {$exists: true}, 'profile.isDummy': {$ne: true}});
console.log('> Found '+allUsers.count()+' users.\n');
allUsers.forEach(function(user){
i++;
// Perform the same transforms done by useraccounts with `lowercaseUsernames` set to `true`
var oldUsername = user.username;
var username = user.username;
username = username.trim().replace(/\s+/gm, ' ');
user.profile.username = user.profile.name || username;
delete user.profile.name;
username = username.toLowerCase().replace(/\s+/gm, '');
user.username = username;
if (user.emails && user.emails.length > 0) {
_.each(user.emails, function(email){
email.address = email.address.toLowerCase().replace(/\s+/gm, '');
});
}
console.log('> Updating user '+user._id+' ('+oldUsername+' -> ' + user.username + ')');
try {
Meteor.users.update(user._id, {
$set: {
emails: user.emails,
profile: user.profile,
username: user.username,
},
});
}
catch (err) {
console.warn('> Unable to convert username ' + user.username + ' to lowercase!');
console.warn('> Please try to fix it by hand!! :(');
}
});
return i;
},
changeColorNames: function () {
var i = 0;
var settings = Telescope.settings.collection.findOne();
var set = {};
if (!!settings) {
if (!!settings.buttonColor)
set.accentColor = settings.buttonColor;
if (!!settings.buttonTextColor)
set.accentContrastColor = settings.buttonTextColor;
if (!!settings.buttonColor)
set.secondaryColor = settings.headerColor;
if (!!settings.buttonColor)
set.secondaryContrastColor = settings.headerTextColor;
if (!_.isEmpty(set)) {
Telescope.settings.collection.update(settings._id, {$set: set}, {validate: false});
}
}
return i;
},
migrateUserProfiles: function () {
var i = 0;
var allUsers = Meteor.users.find({telescope: {$exists: false}});
console.log('> Found '+allUsers.count()+' users.\n');
allUsers.forEach(function(user){
i++;
console.log('> Updating user '+user._id+' (' + user.username + ')');
var telescopeUserData = {};
// loop over user data schema
_.each(Telescope.schemas.userData._schema, function (property, key) {
if (!!user[key]) { // look for property on root of user object
telescopeUserData[key] = user[key];
} else if (user.votes && !!user.votes[key]) { // look for it in user.votes object
telescopeUserData[key] = user.votes[key];
} else if (user.profile && user.profile[key]) { // look for it in user.profile object
telescopeUserData[key] = user.profile[key];
}
});
// console.log(telescopeUserData);
try {
Meteor.users.update(user._id, {
$set: {
telescope: telescopeUserData
}
});
} catch (err) {
console.log(err);
console.warn('> Unable to migrate profile for user ' + user.username);
}
});
return i;
},
migrateEmailHash: function () {
var i = 0;
var allUsers = Meteor.users.find({$and: [{"email_hash": {$exists: true}}, {"telescope.emailHash": {$exists: false}}]});
console.log('> Found '+allUsers.count()+' users.\n');
allUsers.forEach(function(user){
i++;
console.log('> Updating user '+user._id+' (' + user.username + ')');
var emailHash = user.email_hash;
if (!!emailHash) {
Meteor.users.update(user._id, {$set: {"telescope.emailHash": emailHash}});
}
});
return i;
},
// addTopLevelCommentIdToComments: function() {
// var i = 0;
// // find all root comments and set topLevelCommentId on their root children
// Comments.find({parentCommentId: {$exists : false}}).forEach(function (comment) {
// // topLevelCommentId is the root comment._id
// var topLevelCommentId = comment._id;
// console.log("Root Comment found: " + topLevelCommentId);
// // find childComments that have this root comment as parentCommentId
// Comments.find({parentCommentId: comment._id}).forEach(function (childComment) {
// i++;
// updateParentAndChild(topLevelCommentId, childComment._id);
// });
// });
// function updateParentAndChild(topLevelCommentId, parentId) {
// i++;
// console.log("Parent Comment: " + parentId, " top level comment " + topLevelCommentId);
// Comments.update(parentId, {$set: {'topLevelCommentId': topLevelCommentId}}, {multi: false, validate: false});
// var childComments = Comments.find({topLevelCommentId: {$exists : false}, parentCommentId: parentId});
// console.log('> Found '+childComments.count()+' child comments.\n');
// childComments.forEach(function(childComment){
// i++;
// // find all nested childComments and set topLevelCommentId
// console.log("Child Comment: " + childComment._id, " top level comment " + topLevelCommentId);
// // set nested childComment to use parent's topLevelCommentId
// Comments.update(childComment._id, {$set: {'topLevelCommentId': topLevelCommentId}}, {multi: false, validate: false});
// updateParentAndChild(topLevelCommentId, childComment._id, true);
// });
// }
// console.log("---------------------");
// return i;
// },
migrateDisplayName: function () {
var i = 0;
var displayName;
var allUsers = Meteor.users.find({"telescope.displayName": {$exists: false}});
console.log('> Found '+allUsers.count()+' users.\n');
allUsers.forEach(function(user){
i++;
console.log('> Updating user '+user._id+' (' + user.username + ')');
if (!!user.profile) {
displayName = user.profile.name || user.profile.username;
} else {
displayName = user.username;
}
console.log('name: ', displayName);
if (!!displayName) {
Meteor.users.update(user._id, {$set: {"telescope.displayName": displayName}});
} else {
console.log("displayName not found :(");
}
});
return i;
},
migrateNewsletterSettings: function () {
var i = 0;
var allUsers = Meteor.users.find({
$or: [
{"profile.showBanner": {$exists: true}},
{"profile.subscribedToNewsletter": {$exists: true}}
]
});
console.log('> Found '+allUsers.count()+' users.\n');
allUsers.forEach(function(user){
i++;
var displayName;
if (!!user.profile) {
displayName = user.profile.name || user.profile.username;
} else {
displayName = user.username;
}
console.log('> Updating user '+user._id+' (' + displayName + ')');
if (user.profile) {
var set = {};
var showBanner = user.profile.showBanner;
if (typeof showBanner !== "undefined") {
set["telescope.newsletter.showBanner"] = showBanner;
}
var subscribeToNewsletter = user.profile.subscribedToNewsletter;
if (typeof subscribeToNewsletter !== "undefined") {
set["telescope.newsletter.subscribeToNewsletter"] = subscribeToNewsletter;
}
console.log(set)
if (!_.isEmpty(set)) {
Meteor.users.update(user._id, {$set: set});
}
}
});
return i;
},
addSlugsToPosts: function () {
var i = 0;
Posts.find({slug: {$exists : false}}).forEach(function (post) {
i++;
var slug = Telescope.utils.slugify(post.title);
console.log("Post: "+post._id + " | "+slug);
Posts.update(post._id, { $set: { 'slug': slug}});
console.log("---------------------");
});
return i;
},
updateNewsletterFrequency: function () {
var i = 0;
Telescope.settings.collection.find().forEach(function (setting) {
if (!!setting.newsletterFrequency) {
console.log("Migrating newsletter frequency… ("+setting.newsletterFrequency+")");
i++;
var days;
switch (setting.newsletterFrequency) {
case 1:
days = [1,2,3,4,5,6,7];
break;
case 2:
days = [2,4,6];
break;
case 3:
days = [2,5];
break;
default:
days = [2];
break;
}
Telescope.settings.collection.update(setting._id, { $set: { newsletterFrequency: days } });
}
});
return i;
},
changeOutsideLinksPointTo: function () {
var i = 0;
Telescope.settings.collection.find({outsideLinksPointTo: {$exists : true}}).forEach(function (setting) {
i++;
Telescope.settings.collection.update(setting._id, {$set: {RSSLinksPointTo: setting.outsideLinksPointTo}});
});
return i;
}
};

View file

@ -1,21 +0,0 @@
Package.describe({
name: "migrations",
summary: "Telescope migrations package",
version: "0.27.2-nova",
git: "https://github.com/TelescopeJS/Telescope.git"
});
Package.onUse(function(api) {
api.versionsFrom("METEOR@1.0");
api.use(['nova:core@0.27.2-nova']);
api.addFiles([
'lib/server/migrations.js'
], ['server']);
api.export([
'Migrations'
]);
});

View file

@ -0,0 +1 @@
node_modules

View file

@ -0,0 +1,7 @@
This directory and the files immediately inside it are automatically generated
when you change this package's NPM dependencies. Commit the files in this
directory (npm-shrinkwrap.json, .gitignore, and this README) to source control
so that others run the same versions of sub-dependencies.
You should NOT check in the node_modules directory that Meteor automatically
creates; if you are using git, the .gitignore file tells git to ignore it.

View file

@ -0,0 +1,579 @@
{
"dependencies": {
"abab": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/abab/-/abab-1.0.3.tgz",
"from": "abab@>=1.0.0 <2.0.0"
},
"acorn": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz",
"from": "acorn@>=2.4.0 <3.0.0"
},
"acorn-globals": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-1.0.9.tgz",
"from": "acorn-globals@>=1.0.4 <2.0.0"
},
"amdefine": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
"from": "amdefine@>=0.0.4"
},
"ansi-regex": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz",
"from": "ansi-regex@>=2.0.0 <3.0.0"
},
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"from": "ansi-styles@>=2.2.1 <3.0.0"
},
"asn1": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
"from": "asn1@>=0.2.3 <0.3.0"
},
"assert-plus": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
"from": "assert-plus@>=0.2.0 <0.3.0"
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"from": "asynckit@>=0.4.0 <0.5.0"
},
"aws-sign2": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
"from": "aws-sign2@>=0.6.0 <0.7.0"
},
"aws4": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.5.0.tgz",
"from": "aws4@>=1.2.1 <2.0.0"
},
"bcrypt-pbkdf": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.0.tgz",
"from": "bcrypt-pbkdf@>=1.0.0 <2.0.0"
},
"boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"from": "boolbase@>=1.0.0 <1.1.0"
},
"boom": {
"version": "2.10.1",
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
"from": "boom@>=2.0.0 <3.0.0"
},
"caseless": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
"from": "caseless@>=0.11.0 <0.12.0"
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"from": "chalk@>=1.1.1 <2.0.0"
},
"cheerio": {
"version": "0.20.0",
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.20.0.tgz",
"from": "cheerio@0.20.0"
},
"combined-stream": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
"from": "combined-stream@>=1.0.5 <1.1.0"
},
"commander": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
"from": "commander@>=2.9.0 <3.0.0"
},
"cookie": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.2.3.tgz",
"from": "cookie@0.2.3"
},
"cookie-parser": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.1.tgz",
"from": "cookie-parser@1.4.1"
},
"cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"from": "cookie-signature@1.0.6"
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"from": "core-util-is@>=1.0.0 <1.1.0"
},
"cryptiles": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
"from": "cryptiles@>=2.0.0 <3.0.0"
},
"css-select": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
"from": "css-select@>=1.2.0 <1.3.0"
},
"css-what": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz",
"from": "css-what@>=2.1.0 <2.2.0"
},
"cssom": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.1.tgz",
"from": "cssom@>=0.3.0 <0.4.0"
},
"cssstyle": {
"version": "0.2.37",
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz",
"from": "cssstyle@>=0.2.29 <0.3.0"
},
"dashdash": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
"from": "dashdash@>=1.12.0 <2.0.0",
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"from": "assert-plus@>=1.0.0 <2.0.0"
}
}
},
"deep-is": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
"from": "deep-is@>=0.1.3 <0.2.0"
},
"deepmerge": {
"version": "0.2.10",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-0.2.10.tgz",
"from": "deepmerge@0.2.10"
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"from": "delayed-stream@>=1.0.0 <1.1.0"
},
"dom-serializer": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
"from": "dom-serializer@>=0.1.0 <0.2.0",
"dependencies": {
"domelementtype": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
"from": "domelementtype@>=1.1.1 <1.2.0"
}
}
},
"domelementtype": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
"from": "domelementtype@>=1.0.0 <2.0.0"
},
"domhandler": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz",
"from": "domhandler@>=2.3.0 <2.4.0"
},
"domutils": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
"from": "domutils@1.5.1"
},
"ecc-jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
"from": "ecc-jsbn@>=0.1.1 <0.2.0"
},
"entities": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz",
"from": "entities@>=1.1.1 <1.2.0"
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"from": "escape-string-regexp@>=1.0.2 <2.0.0"
},
"escodegen": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz",
"from": "escodegen@>=1.6.1 <2.0.0"
},
"esprima": {
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
"from": "esprima@>=2.7.1 <3.0.0"
},
"estraverse": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz",
"from": "estraverse@>=1.9.1 <2.0.0"
},
"esutils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
"from": "esutils@>=2.0.2 <3.0.0"
},
"extend": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz",
"from": "extend@>=3.0.0 <3.1.0"
},
"extsprintf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz",
"from": "extsprintf@1.0.2"
},
"fast-levenshtein": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.5.tgz",
"from": "fast-levenshtein@>=2.0.4 <2.1.0"
},
"forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
"from": "forever-agent@>=0.6.1 <0.7.0"
},
"form-data": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.2.tgz",
"from": "form-data@>=2.1.1 <2.2.0"
},
"generate-function": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz",
"from": "generate-function@>=2.0.0 <3.0.0"
},
"generate-object-property": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
"from": "generate-object-property@>=1.1.0 <2.0.0"
},
"getpass": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz",
"from": "getpass@>=0.1.1 <0.2.0",
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"from": "assert-plus@>=1.0.0 <2.0.0"
}
}
},
"graceful-readlink": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
"from": "graceful-readlink@>=1.0.0"
},
"har-validator": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
"from": "har-validator@>=2.0.6 <2.1.0"
},
"has-ansi": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
"from": "has-ansi@>=2.0.0 <3.0.0"
},
"hawk": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
"from": "hawk@>=3.1.3 <3.2.0"
},
"hoek": {
"version": "2.16.3",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
"from": "hoek@>=2.0.0 <3.0.0"
},
"htmlparser2": {
"version": "3.8.3",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
"from": "htmlparser2@>=3.8.1 <3.9.0",
"dependencies": {
"entities": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz",
"from": "entities@>=1.0.0 <1.1.0"
}
}
},
"http-signature": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
"from": "http-signature@>=1.1.0 <1.2.0"
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"from": "inherits@>=2.0.1 <2.1.0"
},
"is-my-json-valid": {
"version": "2.15.0",
"resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz",
"from": "is-my-json-valid@>=2.12.4 <3.0.0"
},
"is-property": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
"from": "is-property@>=1.0.0 <2.0.0"
},
"is-typedarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
"from": "is-typedarray@>=1.0.0 <1.1.0"
},
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"from": "isarray@0.0.1"
},
"isstream": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
"from": "isstream@>=0.1.2 <0.2.0"
},
"jodid25519": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz",
"from": "jodid25519@>=1.0.0 <2.0.0"
},
"jsbn": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.0.tgz",
"from": "jsbn@>=0.1.0 <0.2.0"
},
"jsdom": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-7.2.2.tgz",
"from": "jsdom@>=7.0.2 <8.0.0"
},
"json-schema": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
"from": "json-schema@0.2.3"
},
"json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"from": "json-stringify-safe@>=5.0.1 <5.1.0"
},
"jsonpointer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.0.tgz",
"from": "jsonpointer@>=4.0.0 <5.0.0"
},
"jsprim": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.1.tgz",
"from": "jsprim@>=1.2.2 <2.0.0"
},
"levn": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
"from": "levn@>=0.3.0 <0.4.0"
},
"lodash": {
"version": "4.17.2",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.2.tgz",
"from": "lodash@>=4.1.0 <5.0.0"
},
"mime-db": {
"version": "1.25.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.25.0.tgz",
"from": "mime-db@>=1.25.0 <1.26.0"
},
"mime-types": {
"version": "2.1.13",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.13.tgz",
"from": "mime-types@>=2.1.7 <2.2.0"
},
"nth-check": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz",
"from": "nth-check@>=1.0.1 <1.1.0"
},
"nwmatcher": {
"version": "1.3.9",
"resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.3.9.tgz",
"from": "nwmatcher@>=1.3.7 <2.0.0"
},
"oauth-sign": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
"from": "oauth-sign@>=0.8.1 <0.9.0"
},
"optionator": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
"from": "optionator@>=0.8.1 <0.9.0"
},
"parse5": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz",
"from": "parse5@>=1.5.1 <2.0.0"
},
"pinkie": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
"from": "pinkie@>=2.0.0 <3.0.0"
},
"pinkie-promise": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
"from": "pinkie-promise@>=2.0.0 <3.0.0"
},
"prelude-ls": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
"from": "prelude-ls@>=1.1.2 <1.2.0"
},
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"from": "punycode@>=1.4.1 <2.0.0"
},
"qs": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.3.0.tgz",
"from": "qs@>=6.3.0 <6.4.0"
},
"readable-stream": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"from": "readable-stream@>=1.1.0 <1.2.0"
},
"request": {
"version": "2.79.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz",
"from": "request@>=2.55.0 <3.0.0"
},
"sax": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
"from": "sax@>=1.1.4 <2.0.0"
},
"sntp": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
"from": "sntp@>=1.0.0 <2.0.0"
},
"source-map": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
"from": "source-map@>=0.2.0 <0.3.0"
},
"sshpk": {
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.10.1.tgz",
"from": "sshpk@>=1.7.0 <2.0.0",
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"from": "assert-plus@>=1.0.0 <2.0.0"
}
}
},
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"from": "string_decoder@>=0.10.0 <0.11.0"
},
"stringstream": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
"from": "stringstream@>=0.0.4 <0.1.0"
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"from": "strip-ansi@>=3.0.0 <4.0.0"
},
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"from": "supports-color@>=2.0.0 <3.0.0"
},
"symbol-tree": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.1.4.tgz",
"from": "symbol-tree@>=3.1.0 <4.0.0"
},
"tough-cookie": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz",
"from": "tough-cookie@>=2.2.0 <3.0.0"
},
"tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"from": "tr46@>=0.0.1 <0.1.0"
},
"tunnel-agent": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
"from": "tunnel-agent@>=0.4.1 <0.5.0"
},
"tweetnacl": {
"version": "0.14.3",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.3.tgz",
"from": "tweetnacl@>=0.14.0 <0.15.0"
},
"type-check": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
"from": "type-check@>=0.3.2 <0.4.0"
},
"uuid": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.0.tgz",
"from": "uuid@>=3.0.0 <4.0.0"
},
"verror": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz",
"from": "verror@1.3.6"
},
"webidl-conversions": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-2.0.1.tgz",
"from": "webidl-conversions@>=2.0.0 <3.0.0"
},
"whatwg-url-compat": {
"version": "0.6.5",
"resolved": "https://registry.npmjs.org/whatwg-url-compat/-/whatwg-url-compat-0.6.5.tgz",
"from": "whatwg-url-compat@>=0.6.5 <0.7.0"
},
"wordwrap": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
"from": "wordwrap@>=1.0.0 <1.1.0"
},
"xml-name-validator": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz",
"from": "xml-name-validator@>=2.0.1 <3.0.0"
},
"xtend": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
"from": "xtend@>=4.0.0 <5.0.0"
}
}
}

View file

@ -1,30 +0,0 @@
// /*
// Wrapper for the Movies components
// */
// import Telescope from 'meteor/nova:lib';
// import React, { PropTypes, Component } from 'react';
// import { Accounts } from 'meteor/std:accounts-ui';
// import { FlashContainer } from "meteor/nova:core";
// const Layout = props => {
// return (
// <div className="wrapper">
// <div style={{maxWidth: "300px"}}>
// <Accounts.ui.LoginForm />
// </div>
// <FlashContainer component={Telescope.components.FlashMessages}/>
// <div className="main">
// {this.props.children}
// </div>
// </div>
// )
// }
// export default Layout;

View file

@ -0,0 +1 @@
import './lib/modules.js';

View file

@ -7,7 +7,6 @@ it the same way.
import Telescope from 'meteor/nova:lib';
import React from 'react';
import { IndexLink } from 'react-router';
import { withCurrentUser } from 'meteor/nova:core';
import Users from 'meteor/nova:users';
const CustomLogo = ({logoUrl, siteTitle, currentUser}) => {
@ -19,4 +18,4 @@ const CustomLogo = ({logoUrl, siteTitle, currentUser}) => {
)
}
Telescope.replaceComponent('Logo', CustomLogo, withCurrentUser);
Telescope.replaceComponent('Logo', CustomLogo);

View file

@ -68,4 +68,51 @@ CustomPostsItem.propTypes = {
post: React.PropTypes.object.isRequired
};
CustomPostsItem.fragmentName = 'PostsItemFragment';
CustomPostsItem.fragment = gql`
fragment PostsItemFragment on Post {
_id
title
url
slug
thumbnailUrl
baseScore
postedAt
sticky
status
categories {
# ...minimumCategoryInfo
_id
name
slug
}
commentCount
commenters {
# ...avatarUserInfo
_id
__displayName
__emailHash
__slug
}
upvoters {
_id
}
downvoters {
_id
}
upvotes # should be asked only for admins?
score # should be asked only for admins?
viewCount # should be asked only for admins?
clickCount # should be asked only for admins?
user {
# ...avatarUserInfo
_id
__displayName
__emailHash
__slug
}
color
}
`;
Telescope.replaceComponent('PostsItem', CustomPostsItem);

View file

@ -1,5 +1,4 @@
import Posts from "meteor/nova:posts";
import Users from 'meteor/nova:users';
/*
Let's assign a color to each post (why? cause we want to, that's why).
@ -7,13 +6,6 @@ We'll do that by adding a custom field to the Posts collection.
Note that this requires our custom package to depend on nova:posts and nova:users.
*/
// check if user can create a new post
const canInsert = user => Users.canDo(user, "posts.new");
// check if user can edit a post
const canEdit = Users.canEdit;
const alwaysPublic = user => true;
Posts.addField(
{
fieldName: 'color',
@ -21,9 +13,9 @@ Posts.addField(
type: String,
control: "select", // use a select form control
optional: true, // this field is not required
insertableIf: canInsert,
editableIf: canEdit,
viewableIf: alwaysPublic,
insertableIf: ['default'],
editableIf: ['default'],
viewableIf: ['default'],
form: {
options: function () { // options for the select form control
return [

View file

@ -0,0 +1,14 @@
/*
Let's import all our files here.
*/
import "./callbacks.js"
import "./emails.js"
import "./custom_fields.js"
import "./i18n.js"
import "./groups.js"
import "./routes.jsx"
import "./components/CustomLogo.jsx";
import "./components/CustomNewsletter.jsx";
import "./components/CustomPostsItem.jsx";

View file

@ -15,6 +15,9 @@ Package.onUse( function(api) {
'nova:users'
]);
api.mainModule('server.js', 'server');
api.mainModule('client.js', 'client');
api.addFiles([
'lib/modules.js'
], ['client', 'server']);

View file

@ -0,0 +1,2 @@
import './lib/modules.js';
import './lib/server/templates.js';

View file

@ -4,11 +4,7 @@ Wrapper for the Movies components
*/
import Telescope from 'meteor/nova:lib';
import React, { PropTypes, Component } from 'react';
import NovaForm from 'meteor/nova:forms';
import { Button } from 'react-bootstrap';
import { FlashContainer } from 'meteor/nova:core';
import Accounts from './Accounts.jsx';
import MoviesList from './MoviesList.jsx';

Some files were not shown because too many files have changed in this diff Show more