Pull to refresh

Meteor. А теперь загрузка фоточек

Reading time3 min
Views10K
Это же очень просто (ага, когда есть пример).

[демо] — мультизагрузка с линейками прогресса, требуется регистрация.
[исходники] — комментарии по коду ниже.

1)
Стартую Метеор.
$ meteor create meteor-demo-cfs
$ cd meteor-demo-cfs
$ meteor
Чтобы не мешался экран терминала, запускаю в консоли [ctrl]+[alt]+[f4]; обратное переключение по [ctrl]+[alt]+[f7]. Это в Ubuntu.

2)
Редактирую ./meteor/packages — джентльменский набор пакетов.
meteor-platform
coffeescript
less
mquandalle:jade
accounts-password
ian:accounts-ui-bootstrap-3
twbs:bootstrap
cfs:standard-packages
cfs:filesystem
cfs:gridfs
cfs:ui
Метеор сам все поставит, как только файл будет сохранен.

3)
Удаляю ботву — все файлы из корня проекта (.js, .html, .css). Добавляю: main.coffee, main.jade, main.less.

4)
main.coffee
# вымораживает же набирать
cl = (something) ->
  console.log(something)

# лениво же регистрироваться
config = admin: email: 'demo@example.com', password: '12345678'
if Meteor.isServer
  Meteor.startup ->
    if Meteor.users.find().count() is 0
      seedUserId = Accounts.createUser
        email: config.admin.email,
        password: config.admin.password

# photoStore - где будем хранить файлы, дополнительные опции закомментированы
# https://github.com/CollectionFS/Meteor-CollectionFS#storage-adapters
if Meteor.isClient
  # photoStore = new FS.Store.FileSystem 'photos'
  photoStore = new FS.Store.GridFS 'photos'
if Meteor.isServer
  # photoStore = new FS.Store.FileSystem 'photos'
  photoStore = new FS.Store.GridFS 'photos',
    # mongoUrl: 'mongodb://127.0.0.1:27017/test/', # optional, defaults to Meteor's local MongoDB
    # mongoOptions: {...},  # optional, see note below
    # transformWrite: myTransformWriteFunction, # optional
    # transformRead: myTransformReadFunction, # optional
    # maxTries: 1, # optional, default 5
    # chunkSize: 1024*1024  # optional, default GridFS chunk size in bytes (can be overridden per file).
    #                      # Default: 2MB. Reasonable range: 512KB - 4MB
    {}

# коллекция с картинками
Photos = new FS.Collection 'photos',
  stores: [photoStore]
  filter: allow: contentTypes: ['image/*'] # allow only images in this FS.Collection

# про права доступа https://github.com/CollectionFS/Meteor-CollectionFS#security
Photos.allow
  insert: (userId, file) ->
    userId and file.metadata?.userId is userId
  update: (userId, file, fieldNames, modifier) ->
    userId and file.metadata?.userId is userId
  remove: (userId, file) ->
    userId and file.metadata?.userId is userId
  download: (userId, file, shareId) ->
    true
  fetch: ['metadata.userId', 'original']

if Meteor.isClient
  # список вновь загруженных файлов
  newUpload = []
  Meteor.startup ->
    Tracker.autorun ->
      if not Meteor.userId()
        # reset, если мы потеряли пользователя
        newUpload = []
  Template.hello.events
    'change input[type="file"]': (event, template) ->
      # FileAPI http://caniuse.com/#search=fileapi
      # или http://habrahabr.ru/company/mailru/blog/201010/
      files = event.target.files
      count = files.length
      i = 0
      while i < count
        newFile = new FS.File(files[i])
        # цепляю к файлу свои метаданные https://github.com/CollectionFS/Meteor-CollectionFS#add-custom-metadata-to-a-file-before-inserting
        newFile.metadata = userId: Meteor.userId()
        Photos.insert newFile, (error, file) ->
          throw error if error
          # If !error, we have inserted new doc with ID file._id, and
          # kicked off the data upload using HTTP
          cl file
        i++
  Template.hello.helpers
    # передаю в шаблон mongo-курсор
    photos: ->
      Photos.find()
    # это чтобы показывать progress-bar
    isNewUpload: ->
      if newUpload.indexOf(this._id) + 1
        return true
      unless this.isUploaded()
        newUpload.push(this._id)
        return true
      return false

# подписка на данные http://ru.discovermeteor.com/chapters/publications-and-subscriptions/
if Meteor.isServer
  Meteor.publish 'photos', (limit) ->
    check(arguments, [Match.Any])
    [
      Photos.find({}, {limit: limit})
    ]
if Meteor.isClient
  Meteor.subscribe 'photos', 100


5)
Публикую.
$ meteor deploy demo-cfs.meteor.com


Сцылки.
  • Минимальный набор для старта CoffeeScript:
  • Jade — скоростная верстка. Меньше кодинга, больше COD.
  • Less — скоростной css. Меньше кодинга, больше COD.
  • Про MongoDB.
  • Про Meteor-CollectionFS.
  • Про Метеор.
  • Atom — прекрасный инструмент для кодинга в Метеоре от создателей GitHub. Дополнительно пакеты: Stylus, Sublime-Style-Column-Selection, language-jade, meteor-snippets, todo-show.
Tags:
Hubs:
Total votes 12: ↑5 and ↓7-2
Comments7

Articles