Popular Tags:

Генерация тестовых данных на C#

02.10.2017 at 22:20

Для генерации данных я использую библиотеку Bogus. Начнем с примеров:

using Bogus;
using Bogus.DataSets;
...
var faker = new Faker();
Console.WriteLine(faker.Company.CompanyName()); //Keebler LLC
Console.WriteLine(faker.Name.FullName(Name.Gender.Male)); //Werner Rath
Console.WriteLine(faker.Image.Animals()); //http://lorempixel.com/640/480
Console.WriteLine(faker.Internet.Avatar()); //https://s3.amazonaws.com/uifaces/faces/twitter/rehatkathuria/128.jpg

Методы генерации сгруппированы по датасетам. Bogus умеет генерировать следующие данные:
Address — почтовый индекс, улица, страна, штат, широта и долгота и т.д. read more

Парсинг сайтов на C#

11.09.2017 at 11:55

Использование Selenium на C#

Самый распостраненный способ автоматизировать любые действия с вебсайтом — использование библиотеки Selenium. Эта библиотека позволяет запустить браузер и управлять всеми действиями в нем. Поддерживаются все распостраненные браузеры.

Подключение Selenium к проекту

В контекстном меню проекта выбираем пункт «Manage NuGet Packages…»

Далее на вкладке «Browse» находим и устанавливаем пакеты Selenium.WebDriver и Selenium.WebDriver.ChromeDriver. read more

Как писать на C# на linux

23.08.2017 at 22:02


Я почти год не писал на C#, переквалифицировался в Dart разработчика и пересел на ubuntu как нормальный фронтендер. За это время в мире дот нета произошло много всего интересного, что прошло мимо меня. Например вышел .Net Core 2.0, что позволило писать приложения на линуксе. С первой версией конечно тоже можно было, но я стараюсь не использовать ничего от Microsoft первой версии. read more

Шпаргалка по Git

22.08.2017 at 21:30


Решил написать свою шпаргалку, чтобы постоянно не гуглить одни и те же вопросы.

Клонирование репозитория

git clone ssh://user@domain.com/repo.git

Добавить файл к следующему коммиту

git add <filename>

Закоммитить

git commit -m "Commit message"

Подтянуть все изменения с сервера

git pull

Удаление всех незапушенных коммитов

git reset --hard HEAD~1

Изменить комментарий к последнему коммиту

git commit --amend

Список всех локальных веток

git branch

Переключиться на ветку

git checkout <branchname>

Обновление информации с сервера

git fetch

Замержить другую ветку в текущую

git merge <otherbranchname> 

Откатить запушенный коммит (создаст локальный коммит с откатом)

git revert <commit_hash>

Для того, чтобы некоторые файлы не попадали под управление системы контроля версий, нужно их прописать в файле .gitignore read more

Разработка простой игры на phaser.io. Продолжение.

02.08.2017 at 19:15

StateManager в phaser.io

Во всех игровых движках есть какой-либо способ управления различными состояниями игры. В phaser за это отвечает StateManager. Доступ к нему осуществляется с помощью свойства game.state.
Добавляется новое состояние с помощью метода

game.state.add('gameOver', gameOverState);

Состояние представляет собой объект, который может реализовать несколько предопределенных функций.

var gameState = {
    create: function () {
    },
    update: function () {
    },
    preload: function () {
    },
    init: function (param) {
    }
}

Есть и другие функции, полный список можно посмотреть в API. read more

Разработка простой игры на phaser.io

01.08.2017 at 13:22


Для знакомства с очередным игровым движком я всегда использую одну и ту же игру HitMeBrick. Посмотрим, как написать ее на phaser.

За основу я взял официальный туториал.

Сначала дорабатываем инициализацию

function create() {
    game.physics.startSystem(Phaser.Physics.ARCADE);
    game.add.sprite(0, 0, 'sky');
    initGround();
    initPlayer();
    bricks = game.add.group();
    bricks.enableBody = true;
    scoreText = game.add.text(16, 16, 'score: 0', { fontSize: '32px', fill: '#000' });
    livesText = game.add.text(16, 64, 'lives: 5', { fontSize: '32px', fill: '#000' });
    gameOverText = game.add.text(16, 112, '', { fontSize: '32px', fill: '#000' });
    leftKey = game.input.keyboard.addKey(Phaser.Keyboard.LEFT);
    rightKey = game.input.keyboard.addKey(Phaser.Keyboard.RIGHT);
}

Здесь я вынес в отдельные функции инициализацию игрока и земли, они практически не изменились. read more

Использование quill.js

19.07.2017 at 21:57


quill.js — это браузерный редактор текста, имеющий достаточно простое API. Встраивается он очень просто.

Сначала нужно подключить библиотеку

<script src="http://cdn.quilljs.com/1.3.0/quill.min.js"></script>
<link href="http://cdn.quilljs.com/1.3.0/quill.snow.css" rel="stylesheet">

Если планируется использовать редактор формул, то нужно так же подключить KaTeX

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.css" integrity="sha384-wITovz90syo1dJWVh32uuETPVEtGigN07tkttEqPv+uR2SE/mbQcG7ATL28aI9H0" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.js" integrity="sha384-/y1Nn9+QQAipbNQWU65krzJralCnuOasHncUFXGkdwntGeSvQicrYkiUBwsgUqc1" crossorigin="anonymous"></script>

Теперь инициализируем редактор

var quill = new Quill('#text-editor', {
  modules: {
    formula: true,
    toolbar: [
      ['bold', 'italic', 'underline', 'strike'],
      ['image', 'blockquote', 'code-block'],
      [{ 'list': 'ordered'}, { 'list': 'bullet' }],
      [{ 'indent': '-1'}, { 'indent': '+1' }],
      [{ 'size': ['small', false, 'large', 'huge'] }],
      [{ 'header': [1, 2, 3, 4, 5, 6, false] }],
      [{ 'color': [] }, { 'background': [] }],
      [{ 'font': [] }],
      [{ 'align': [] }],
      ['formula'],
      ['clean']     
    ]
  },
  placeholder: 'Write your text here',
  theme: 'snow'
});

Первым параметром передается селектор элемента, который будет контейнером для редактора. read more

Подключение relap.io в wordpress

12.07.2017 at 18:24


relap.io — это сервис, предлагающий вашим посетителям контент с вашего сайта, и основным преимуществом является алгоритм рекомендации контента. Разработали его в SurfingBird, что позволяет надеяться на то, что алгоритм работает хорошо.

Добавить виджет с такими рекомендациями совсем не трудно:

1. Регистрируемся в сервисе

2. На странице https://relap.io/widgets регистрируем домен. Сервис заработает на домене не сразу, а минут через 20. read more

Создание блога на Dart. Часть 3.

12.07.2017 at 18:02


Создание блога на Dart. Часть 1.
Создание блога на Dart. Часть 2.
Создание блога на Dart. Часть 3.

Хранение данных

Для Dart написаны драйверы практически для всех популярных СУБД. Я решил использовать PostgreSQL. Драйвер подключается в пабспеке:

dependencies:
  ...
  postgresql: ^0.3.4

К полям в результатах запроса можно обращаться по алиасам

class PostRepository {
  Future<List<Post>> getAllPosts() async {
    var result = new List<Post>();

    var dbUserName = Config.dbUserName;
    var dbUserPass = Config.dbUserPass;
    var dbServerHost = Config.dbServerHost;
    var dbServerPort = Config.dbServerPort;
    var dbName = Config.dbName;

    var uri =
        'postgres://$dbUserName:$dbUserPass@$dbServerHost:$dbServerPort/$dbName';
    Connection connection = await connect(uri);
    List<Row> rows = await connection
        .query(
            'SELECT title, body, tags, permalink, created, updated FROM public.posts;')
        .toList();
    for (var i = 0; i < rows.length; i++) {
      Row row = rows[i];
      result.add(new Post(row.title, row.body, (row.tags as String).split(','),
          row.permalink, row.created, row.updated));
    }
    connection.close();
    return result;
  }
}

Класс поста для понимания:

class Post {
  String title;
  String body;
  List<String> tags;
  String permalink;
  DateTime created;
  DateTime updated;

  Post(this.title, this.body, this.tags, this.permalink, this.created, this.updated);
}
read more

Создание блога на Dart. Часть 2.

12.07.2017 at 18:01


Создание блога на Dart. Часть 1.
Создание блога на Dart. Часть 2.
Создание блога на Dart. Часть 3.

Роутинг

Роутинг я реализовал просто — обработкой запросов занимаются контроллеры, каждый из которых сам решает, может он обработать запрос или нет. Запрос обрабатывается первым подходящим контроллером.

Класс базового контроллера:

abstract class ControllerBase {
  Future processRequest(HttpRequest request);
  Future<bool> canProcessRequest(HttpRequest request);   
}

Базовый класс для контроллеров, возвращающих HTML:

abstract class HttpController extends ControllerBase {
  Future processRequest(HttpRequest request)  async {
    request.response.headers.contentType = ContentType.HTML;    
  }
}

Класс контроллера, отдающего содержимое поста по пермалинку:

class PostController extends HttpController {
  PostRepository postRepository = injector.get(PostRepository);
  PostController() {}

  Future processRequest(HttpRequest request) async {
    await super.processRequest(request);
    var requestPermalink = StringUtils.Trim(request.requestedUri.path, '/');
    postRepository.getAllPosts().then((List<Post> posts) {
      var post = posts.where((p) => p.permalink == requestPermalink).single;
      request.response
        ..write(post.body)
        ..close();
    });
  }

  Future<bool> canProcessRequest(HttpRequest request) {
    var requestPermalink = StringUtils.Trim(request.requestedUri.path, '/');
    return postRepository.getAllPosts().then((List<Post> posts) {
      return posts.any((p) => p.permalink == requestPermalink);
    });
  }
}

Урл для этого контроллера выглядит так: /permalink

Из репозитория постов получаются все посты, из них выбирается единственный с соответствующим пермалинком и в ответ пишется содержимое поста. read more