diff --git a/.gitignore b/.gitignore index 57a1574..2867286 100644 --- a/.gitignore +++ b/.gitignore @@ -194,3 +194,13 @@ FakesAssemblies/ # Visual Studio 6 workspace options file *.opt + + +# Created by https://www.gitignore.io +# +### XamarinStudio ### +bin/ +obj/ +*.userprefs + + diff --git a/README.md b/README.md index 4ceb1eb..8dbea08 100644 --- a/README.md +++ b/README.md @@ -4,3 +4,6 @@ English readme not available at this time, it's only available in [french](readme.fr.md) + +Berezovskiy Egor + diff --git a/Students/berezovskiy-egor-cathelineau-florian/nget-v1/.gitignore b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/.gitignore new file mode 100644 index 0000000..59a1c90 --- /dev/null +++ b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/.gitignore @@ -0,0 +1,12 @@ +/RUNNING_PID +/logs/ +/project/*-shim.sbt +/project/project/ +/project/target/ +/target/ + +*.iml +## Directory-based project format: +.idea/ +/out/ +.idea_modules/ diff --git a/Students/berezovskiy-egor-cathelineau-florian/nget-v1/LICENSE b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/LICENSE new file mode 100644 index 0000000..6c42406 --- /dev/null +++ b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/LICENSE @@ -0,0 +1,13 @@ +Copyright 2014 Typesafe, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/Students/berezovskiy-egor-cathelineau-florian/nget-v1/activator b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/activator new file mode 100755 index 0000000..c4e5755 --- /dev/null +++ b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/activator @@ -0,0 +1,334 @@ +#!/usr/bin/env bash + +### ------------------------------- ### +### Helper methods for BASH scripts ### +### ------------------------------- ### + +realpath () { +( + TARGET_FILE="$1" + + cd "$(dirname "$TARGET_FILE")" + TARGET_FILE=$(basename "$TARGET_FILE") + + COUNT=0 + while [ -L "$TARGET_FILE" -a $COUNT -lt 100 ] + do + TARGET_FILE=$(readlink "$TARGET_FILE") + cd "$(dirname "$TARGET_FILE")" + TARGET_FILE=$(basename "$TARGET_FILE") + COUNT=$(($COUNT + 1)) + done + + if [ "$TARGET_FILE" == "." -o "$TARGET_FILE" == ".." ]; then + cd "$TARGET_FILE" + TARGET_FILEPATH= + else + TARGET_FILEPATH=/$TARGET_FILE + fi + + # make sure we grab the actual windows path, instead of cygwin's path. + if ! is_cygwin; then + echo "$(pwd -P)/$TARGET_FILE" + else + echo $(cygwinpath "$(pwd -P)/$TARGET_FILE") + fi +) +} + +# TODO - Do we need to detect msys? + +# Uses uname to detect if we're in the odd cygwin environment. +is_cygwin() { + local os=$(uname -s) + case "$os" in + CYGWIN*) return 0 ;; + *) return 1 ;; + esac +} + +# This can fix cygwin style /cygdrive paths so we get the +# windows style paths. +cygwinpath() { + local file="$1" + if is_cygwin; then + echo $(cygpath -w $file) + else + echo $file + fi +} + +# Make something URI friendly +make_url() { + url="$1" + local nospaces=${url// /%20} + if is_cygwin; then + echo "/${nospaces//\\//}" + else + echo "$nospaces" + fi +} + +# Detect if we should use JAVA_HOME or just try PATH. +get_java_cmd() { + if [[ -n "$JAVA_HOME" ]] && [[ -x "$JAVA_HOME/bin/java" ]]; then + echo "$JAVA_HOME/bin/java" + else + echo "java" + fi +} + +echoerr () { + echo 1>&2 "$@" +} +vlog () { + [[ $verbose || $debug ]] && echoerr "$@" +} +dlog () { + [[ $debug ]] && echoerr "$@" +} +execRunner () { + # print the arguments one to a line, quoting any containing spaces + [[ $verbose || $debug ]] && echo "# Executing command line:" && { + for arg; do + if printf "%s\n" "$arg" | grep -q ' '; then + printf "\"%s\"\n" "$arg" + else + printf "%s\n" "$arg" + fi + done + echo "" + } + + exec "$@" +} +addJava () { + dlog "[addJava] arg = '$1'" + java_args=( "${java_args[@]}" "$1" ) +} +addApp () { + dlog "[addApp] arg = '$1'" + sbt_commands=( "${app_commands[@]}" "$1" ) +} +addResidual () { + dlog "[residual] arg = '$1'" + residual_args=( "${residual_args[@]}" "$1" ) +} +addDebugger () { + addJava "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=$1" +} +addConfigOpts () { + dlog "[addConfigOpts] arg = '$*'" + for item in $* + do + addJava "$item" + done +} +# a ham-fisted attempt to move some memory settings in concert +# so they need not be messed around with individually. +get_mem_opts () { + local mem=${1:-1024} + local meta=$(( $mem / 4 )) + (( $meta > 256 )) || meta=256 + (( $meta < 1024 )) || meta=1024 + + # default is to set memory options but this can be overridden by code section below + memopts="-Xms${mem}m -Xmx${mem}m" + if [[ "${java_version}" > "1.8" ]]; then + extmemopts="-XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=${meta}m" + else + extmemopts="-XX:PermSize=64m -XX:MaxPermSize=${meta}m" + fi + + if [[ "${java_opts}" == *-Xmx* ]] || [[ "${java_opts}" == *-Xms* ]] || [[ "${java_opts}" == *-XX:MaxPermSize* ]] || [[ "${java_opts}" == *-XX:ReservedCodeCacheSize* ]] || [[ "${java_opts}" == *-XX:MaxMetaspaceSize* ]]; then + # if we detect any of these settings in ${java_opts} we need to NOT output our settings. + # The reason is the Xms/Xmx, if they don't line up, cause errors. + memopts="" + extmemopts="" + fi + + echo "${memopts} ${extmemopts}" +} +require_arg () { + local type="$1" + local opt="$2" + local arg="$3" + if [[ -z "$arg" ]] || [[ "${arg:0:1}" == "-" ]]; then + die "$opt requires <$type> argument" + fi +} +is_function_defined() { + declare -f "$1" > /dev/null +} + +# If we're *not* running in a terminal, and we don't have any arguments, then we need to add the 'ui' parameter +detect_terminal_for_ui() { + [[ ! -t 0 ]] && [[ "${#residual_args}" == "0" ]] && { + addResidual "ui" + } + # SPECIAL TEST FOR MAC + [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]] && [[ "${#residual_args}" == "0" ]] && { + echo "Detected MAC OSX launched script...." + echo "Swapping to UI" + addResidual "ui" + } +} + +# Processes incoming arguments and places them in appropriate global variables. called by the run method. +process_args () { + while [[ $# -gt 0 ]]; do + case "$1" in + -h|-help) usage; exit 1 ;; + -v|-verbose) verbose=1 && shift ;; + -d|-debug) debug=1 && shift ;; + -mem) require_arg integer "$1" "$2" && app_mem="$2" && shift 2 ;; + -jvm-debug) + if echo "$2" | grep -E ^[0-9]+$ > /dev/null; then + addDebugger "$2" && shift + else + addDebugger 9999 + fi + shift ;; + -java-home) require_arg path "$1" "$2" && java_cmd="$2/bin/java" && shift 2 ;; + -D*) addJava "$1" && shift ;; + -J*) addJava "${1:2}" && shift ;; + *) addResidual "$1" && shift ;; + esac + done + + is_function_defined process_my_args && { + myargs=("${residual_args[@]}") + residual_args=() + process_my_args "${myargs[@]}" + } +} + +# Actually runs the script. +run() { + # TODO - check for sane environment + + # process the combined args, then reset "$@" to the residuals + process_args "$@" + detect_terminal_for_ui + set -- "${residual_args[@]}" + argumentCount=$# + + #check for jline terminal fixes on cygwin + if is_cygwin; then + stty -icanon min 1 -echo > /dev/null 2>&1 + addJava "-Djline.terminal=jline.UnixTerminal" + addJava "-Dsbt.cygwin=true" + fi + + # run sbt + execRunner "$java_cmd" \ + "-Dactivator.home=$(make_url "$activator_home")" \ + $(get_mem_opts $app_mem) \ + ${java_opts[@]} \ + ${java_args[@]} \ + -jar "$app_launcher" \ + "${app_commands[@]}" \ + "${residual_args[@]}" + + local exit_code=$? + if is_cygwin; then + stty icanon echo > /dev/null 2>&1 + fi + exit $exit_code +} + +# Loads a configuration file full of default command line options for this script. +loadConfigFile() { + cat "$1" | sed '/^\#/d' +} + +### ------------------------------- ### +### Start of customized settings ### +### ------------------------------- ### +usage() { + cat < [options] + + Command: + ui Start the Activator UI + new [name] [template-id] Create a new project with [name] using template [template-id] + list-templates Print all available template names + -h | -help Print this message + + Options: + -v | -verbose Make this runner chattier + -d | -debug Set sbt log level to debug + -mem Set memory options (default: $sbt_mem, which is $(get_mem_opts $sbt_mem)) + -jvm-debug Turn on JVM debugging, open at the given port. + + # java version (default: java from PATH, currently $(java -version 2>&1 | grep version)) + -java-home Alternate JAVA_HOME + + # jvm options and output control + -Dkey=val Pass -Dkey=val directly to the java runtime + -J-X Pass option -X directly to the java runtime + (-J is stripped) + + # environment variables (read from context) + JAVA_OPTS Environment variable, if unset uses "" + SBT_OPTS Environment variable, if unset uses "" + ACTIVATOR_OPTS Environment variable, if unset uses "" + +In the case of duplicated or conflicting options, the order above +shows precedence: environment variables lowest, command line options highest. +EOM +} + +### ------------------------------- ### +### Main script ### +### ------------------------------- ### + +declare -a residual_args +declare -a java_args +declare -a app_commands +declare -r real_script_path="$(realpath "$0")" +declare -r activator_home="$(realpath "$(dirname "$real_script_path")")" +declare -r app_version="1.3.3" + +declare -r app_launcher="${activator_home}/activator-launch-${app_version}.jar" +declare -r script_name=activator +java_cmd=$(get_java_cmd) +declare -r java_opts=( "${ACTIVATOR_OPTS[@]}" "${SBT_OPTS[@]}" "${JAVA_OPTS[@]}" "${java_opts[@]}" ) +userhome="$HOME" +if is_cygwin; then + # cygwin sets home to something f-d up, set to real windows homedir + userhome="$USERPROFILE" +fi +declare -r activator_user_home_dir="${userhome}/.activator" +declare -r java_opts_config_home="${activator_user_home_dir}/activatorconfig.txt" +declare -r java_opts_config_version="${activator_user_home_dir}/${app_version}/activatorconfig.txt" + +# Now check to see if it's a good enough version +declare -r java_version=$("$java_cmd" -version 2>&1 | awk -F '"' '/version/ {print $2}') +if [[ "$java_version" == "" ]]; then + echo + echo No java installations was detected. + echo Please go to http://www.java.com/getjava/ and download + echo + exit 1 +elif [[ ! "$java_version" > "1.6" ]]; then + echo + echo The java installation you have is not up to date + echo Activator requires at least version 1.6+, you have + echo version $java_version + echo + echo Please go to http://www.java.com/getjava/ and download + echo a valid Java Runtime and install before running Activator. + echo + exit 1 +fi + +# if configuration files exist, prepend their contents to the java args so it can be processed by this runner +# a "versioned" config trumps one on the top level +if [[ -f "$java_opts_config_version" ]]; then + addConfigOpts $(loadConfigFile "$java_opts_config_version") +elif [[ -f "$java_opts_config_home" ]]; then + addConfigOpts $(loadConfigFile "$java_opts_config_home") +fi + +run "$@" diff --git a/Students/berezovskiy-egor-cathelineau-florian/nget-v1/activator-launch-1.3.3.jar b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/activator-launch-1.3.3.jar new file mode 100644 index 0000000..59a2a46 Binary files /dev/null and b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/activator-launch-1.3.3.jar differ diff --git a/Students/berezovskiy-egor-cathelineau-florian/nget-v1/build.sbt b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/build.sbt new file mode 100644 index 0000000..c6d16b9 --- /dev/null +++ b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/build.sbt @@ -0,0 +1,15 @@ +name := """ScalaCleanCode""" + +version := "1.0" + +scalaVersion := "2.11.6" + +libraryDependencies ++= Seq( + "org.scalatest" %% "scalatest" % "2.2.4" % "test", + "com.github.scopt" %% "scopt" % "3.3.0", + "com.typesafe.akka" %% "akka-actor" % "2.3.11" +) + +resolvers += Resolver.sonatypeRepo("public") + + diff --git a/Students/berezovskiy-egor-cathelineau-florian/nget-v1/project/build.properties b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/project/build.properties new file mode 100644 index 0000000..f75cdd7 --- /dev/null +++ b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/project/build.properties @@ -0,0 +1,4 @@ +#Activator-generated Properties +#Mon Jun 01 16:04:09 CEST 2015 +template.uuid=7faf8e1e-4e8d-4387-8159-642b50383096 +sbt.version=0.13.8 diff --git a/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/ArgsParser.scala b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/ArgsParser.scala new file mode 100644 index 0000000..5ab7ebb --- /dev/null +++ b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/ArgsParser.scala @@ -0,0 +1,9 @@ +package fr.egor + +class ArgsParser(args: Array[String]) { + def parse(f: (String, Map[String, String]) => Command) = { + args(0) match { + case "get" => ??? + } + } +} diff --git a/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/Command.scala b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/Command.scala new file mode 100644 index 0000000..ff5a175 --- /dev/null +++ b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/Command.scala @@ -0,0 +1,5 @@ +package fr.egor + +trait Command { + def run(): Unit +} diff --git a/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/Config.scala b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/Config.scala new file mode 100644 index 0000000..87539bd --- /dev/null +++ b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/Config.scala @@ -0,0 +1,9 @@ +package fr.egor + +case class Config( + command: String = "", + url: String = "", + path: String = "", + timer: Int = 0, + avg: Boolean = false +) diff --git a/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/GetCommand.scala b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/GetCommand.scala new file mode 100644 index 0000000..0f5e8d5 --- /dev/null +++ b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/GetCommand.scala @@ -0,0 +1,5 @@ +package fr.egor + +case class GetCommand(url: String, options: Map[String, String]) { +} + diff --git a/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/MyApp.scala b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/MyApp.scala new file mode 100644 index 0000000..ddc34a8 --- /dev/null +++ b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/MyApp.scala @@ -0,0 +1,34 @@ +package fr.egor + +import java.io.File + +object MyApp extends App{ + val parser = new scopt.OptionParser[Config]("Nget") { + head("nget", "0.1") + + opt[String]('u', "url") required() valueName("") action { (x, c) => + c.copy(url = x) + } text("The Url") + + cmd("get") action { (_, c) => c.copy(command = "get") } text("Get resource from url") children( + opt[String]('s', "save") required() valueName("") action { (x, c) => + c.copy(path = x) + } text("Save to file") + ) + + cmd("test") action { (_, c) => c.copy(command = "test") } text("Test resource from url") children( + opt[Int]('t', "times") required() valueName("") action { (x, c) => + c.copy(timer = x) + } text("Times is a file"), + + opt[Unit]('a', "avg") action { (_, c) => + c.copy(avg = true) + } text("Times is a file") + ) + } + + parser.parse(args, Config()) match { + case Some(config) => Nget(config) + case None => println("Error") + } +} diff --git a/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/Nget.scala b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/Nget.scala new file mode 100644 index 0000000..df5e53a --- /dev/null +++ b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/Nget.scala @@ -0,0 +1,88 @@ +package fr.egor + +import java.io.File +import java.net.{MalformedURLException, URL} +import java.nio.charset.MalformedInputException +import scala.io.Source +import scala.sys.process._ + +object Nget { + def apply(config: Config): Unit = config match { + + case Config("test", url, _, number, true) => + println(testAvg(url, number.toString)) + + case Config("test", url, _, number, false) => + testUrlConnections(url, number.toString) + + case Config("get", url, path, 0, _) => + try { + new URL(url) #> new File(path) ! + } catch { + case e: Exception => println(e.getMessage) + } + + case Config("get", url, _, _, _) => get(url) match { + case Some(result) => result.foreach(println) + case None => println("Error") + } + + case _ => + println("Wrong args") + } + + def testAvg(url: String, number: String): Long = { + (0 to number.toInt).map { i => + getUrlConnectionTime(url) + }.foldLeft(0l){ + case (acc, Some(i)) => + acc + i + case (acc, None) => + acc + } / number.toInt + } + + def testUrlConnections(url: String, number: String) = { + try { + 0 to number.toInt foreach { i => + getUrlConnectionTime(url) match { + case Some(duration) => + println(s"TEST:$i - duration=${getUrlConnectionTime(url)} ms -> $url") + case None => println(s"TEST:$i - error -> $url") + } + } + } catch { + case e: Exception => println(e.getMessage) + } + } + + def getUrlConnectionTime(url: String): Option[Long] = { + try { + val begin = System.currentTimeMillis() + val connection = new URL(url).openConnection() + connection.setUseCaches(false) + connection.connect() + Some(System.currentTimeMillis() - begin) + } catch { + case e: Exception => None + } + } + + def get(url: String): Option[Iterator[String]] = { + try { + val connection = new URL(url).openConnection() + connection.setUseCaches(false) + val is = connection.getInputStream + val res = Source.fromInputStream(is)(io.Codec("UTF-8")).getLines() + //is.close() + Some(res) + } catch { + case e: MalformedInputException => + println(Console.RED + e.getMessage) + None + case e: MalformedURLException => + println(Console.RED + e.getMessage) + None + } + } +} diff --git a/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/TestCommand.scala b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/TestCommand.scala new file mode 100644 index 0000000..d8aeb1b --- /dev/null +++ b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/main/scala/fr/egor/TestCommand.scala @@ -0,0 +1,4 @@ +package fr.egor + +case class TestCommand(url: String, options: Map[String, String]) { +} diff --git a/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/test/scala/HelloSpec.scala b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/test/scala/HelloSpec.scala new file mode 100644 index 0000000..2017bef --- /dev/null +++ b/Students/berezovskiy-egor-cathelineau-florian/nget-v1/src/test/scala/HelloSpec.scala @@ -0,0 +1,21 @@ +import org.scalatest._ +import fr.egor.Nget + +class ArgsParserTest extends FlatSpec with Matchers { + "Hello" should "have tests" in { + val value = Array("get", "-url", "http//berezovskiy.fr") + val expected = """ + | + | + | + | Bookmarks + | + | + | + | + | + | + |""" + true should === (true) + } +}