<commit_before>require 'stringio'

module Evercam
  module Actors
    class CameraUpdate < Mutations::Command

      required do
        string :id
      end

      optional do
        string :timezone
        string :name
        string :mac_address, :empty => true
        string :model, :empty => true
        string :vendor, :empty => true

        string :jpg_url, :empty => true
        string :mjpg_url, :empty => true
        string :h264_url, :empty => true
        string :audio_url, :empty => true
        string :mpeg_url, :empty => true
        string :external_host, :empty => true
        string :internal_host, :empty => true
        string :external_http_port, :empty => true
        string :internal_http_port, :empty => true
        string :external_rtsp_port, :empty => true
        string :internal_rtsp_port, :empty => true

        string :username
        boolean :is_public
        boolean :is_online

        string :cam_username, :empty => true
        string :cam_password, :empty => true

        string :location_lng, :empty => true
        string :location_lat, :empty => true

        boolean :discoverable
      end

      def validate
        if username && nil == User.by_login(username)
          add_error(:username, :exists, 'Username does not exist')
        end

        unless Camera.by_exid(id)
          add_error(:camera, :exists, 'Camera does not exist')
        end

        if name and name.length > 25
          add_error(:name, :valid, 'Camera Name is too long. Maximum 24 characters.')
        end

        if external_host && !external_host.blank? && !(external_host =~ Evercam::VALID_IP_ADDRESS_REGEX or external_host =~ Evercam::VALID_HOSTNAME_REGEX)
          add_error(:external_host, :valid, 'External host is invalid')
        end

        if internal_host && !internal_host.blank? && !(internal_host =~ Evercam::VALID_IP_ADDRESS_REGEX or internal_host =~ Evercam::VALID_HOSTNAME_REGEX)
          add_error(:internal_host, :valid, 'Internal host is invalid')
        end

        if timezone && false == Timezone::Zone.names.include?(timezone)
          add_error(:timezone, :valid, 'Timezone does not exist or is invalid')
        end

        if !vendor.blank? && Vendor.by_exid(vendor).first.nil?
          add_error(:vendor, :exists, 'Vendor does not exist')
        end

        if !model.blank? && vendor.blank?
          add_error(:model, :valid, 'If you provide model you must also provide vendor')
        end

        if !model.blank? && !vendor.blank? && !Vendor.find(:exid => vendor).nil? && !VendorModel.find(:exid => model, :vendor_id => Vendor.find(:exid => vendor).id)
          add_error(:model, :exists, 'Model does not exist')
        end

        if !mac_address.blank? && !(mac_address =~ /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/)
          add_error(:mac_address, :valid, 'Mac address is invalid')
        end

        if location_lng && nil == location_lat
          add_error(:location_lat, :valid, 'Must provide both location coordinates')
        end

        if location_lat && nil == location_lng
          add_error(:location_lng, :valid, 'Must provide both location coordinates')
        end
      end

      def execute
        camera = ::Camera.by_exid(inputs[:id])

        [:external_http_port, :internal_http_port, :external_rtsp_port, :internal_rtsp_port].each do |port|
          unless inputs[port].nil?
            begin
              camera.values[:config].merge!({"#{port}" => inputs[port].empty? ? '' : Integer(inputs[port])})
            rescue ArgumentError
              add_error(port, :valid, "#{port} is invalid")
              return
            end
          end
        end

        privacy_changed = false
        if inputs.include?(:is_public)
          privacy_changed = (camera.is_public? != inputs[:is_public])
        end

        camera.name = name if name
        camera.owner = User.by_login(username) if username
        camera.is_public = inputs[:is_public] if privacy_changed
        camera.is_online = inputs[:is_online] unless inputs[:is_online].nil?

        [:jpg, :mjpg, :h264, :audio, :mpeg].each do |resource|
          url_name = "#{resource}_url"
          unless inputs[url_name].nil?
            unless inputs[url_name].empty?
              inputs[url_name].prepend('/') if inputs[url_name][0,1] != '/'
            end
            if camera.values[:config].has_key?('snapshots')
              camera.values[:config]['snapshots'].merge!({resource => inputs[url_name]})
            else
              camera.values[:config].merge!({'snapshots' => { resource => inputs[url_name]}})
            end
          end
        end

        if inputs[:cam_username] or inputs[:cam_password]
          camera.values[:config].merge!({'auth' => {'basic' => {'username' => inputs[:cam_username].to_s.empty? ? '' : inputs[:cam_username],
                                                                'password' => inputs[:cam_password].to_s.empty? ? '' : inputs[:cam_password]}}})
        end

        camera.timezone = timezone if timezone
        # Update or reset vendor model
        camera.vendor_model =  VendorModel.find(:exid => model, :vendor_id => Vendor.find(:exid => vendor).id) unless model.blank?
        camera.vendor_model = nil if not model.nil? and model.empty?

        unless inputs[:mac_address].nil?
          camera.mac_address = inputs[:mac_address].empty? ? nil : mac_address
        end

        # setup camera GPS location
        if location_lng.blank? && location_lat.blank?
          camera.location = nil
        else
          begin
            camera.location = { lng: location_lng.to_f, lat: location_lat.to_f }
          rescue ArgumentError<commit_msg>Fix for camera location being reseted if lng&lat parameters aren't present<commit_after>require 'stringio'

module Evercam
  module Actors
    class CameraUpdate < Mutations::Command

      required do
        string :id
      end

      optional do
        string :timezone
        string :name
        string :mac_address, :empty => true
        string :model, :empty => true
        string :vendor, :empty => true

        string :jpg_url, :empty => true
        string :mjpg_url, :empty => true
        string :h264_url, :empty => true
        string :audio_url, :empty => true
        string :mpeg_url, :empty => true
        string :external_host, :empty => true
        string :internal_host, :empty => true
        string :external_http_port, :empty => true
        string :internal_http_port, :empty => true
        string :external_rtsp_port, :empty => true
        string :internal_rtsp_port, :empty => true

        string :username
        boolean :is_public
        boolean :is_online

        string :cam_username, :empty => true
        string :cam_password, :empty => true

        string :location_lng, :empty => true
        string :location_lat, :empty => true

        boolean :discoverable
      end

      def validate
        if username && nil == User.by_login(username)
          add_error(:username, :exists, 'Username does not exist')
        end

        unless Camera.by_exid(id)
          add_error(:camera, :exists, 'Camera does not exist')
        end

        if name and name.length > 25
          add_error(:name, :valid, 'Camera Name is too long. Maximum 24 characters.')
        end

        if external_host && !external_host.blank? && !(external_host =~ Evercam::VALID_IP_ADDRESS_REGEX or external_host =~ Evercam::VALID_HOSTNAME_REGEX)
          add_error(:external_host, :valid, 'External host is invalid')
        end

        if internal_host && !internal_host.blank? && !(internal_host =~ Evercam::VALID_IP_ADDRESS_REGEX or internal_host =~ Evercam::VALID_HOSTNAME_REGEX)
          add_error(:internal_host, :valid, 'Internal host is invalid')
        end

        if timezone && false == Timezone::Zone.names.include?(timezone)
          add_error(:timezone, :valid, 'Timezone does not exist or is invalid')
        end

        if !vendor.blank? && Vendor.by_exid(vendor).first.nil?
          add_error(:vendor, :exists, 'Vendor does not exist')
        end

        if !model.blank? && vendor.blank?
          add_error(:model, :valid, 'If you provide model you must also provide vendor')
        end

        if !model.blank? && !vendor.blank? && !Vendor.find(:exid => vendor).nil? && !VendorModel.find(:exid => model, :vendor_id => Vendor.find(:exid => vendor).id)
          add_error(:model, :exists, 'Model does not exist')
        end

        if !mac_address.blank? && !(mac_address =~ /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/)
          add_error(:mac_address, :valid, 'Mac address is invalid')
        end

        if location_lng && nil == location_lat
          add_error(:location_lat, :valid, 'Must provide both location coordinates')
        end

        if location_lat && nil == location_lng
          add_error(:location_lng, :valid, 'Must provide both location coordinates')
        end
      end

      def execute
        camera = ::Camera.by_exid(inputs[:id])

        [:external_http_port, :internal_http_port, :external_rtsp_port, :internal_rtsp_port].each do |port|
          unless inputs[port].nil?
            begin
              camera.values[:config].merge!({"#{port}" => inputs[port].empty? ? '' : Integer(inputs[port])})
            rescue ArgumentError
              add_error(port, :valid, "#{port} is invalid")
              return
            end
          end
        end

        privacy_changed = false
        if inputs.include?(:is_public)
          privacy_changed = (camera.is_public? != inputs[:is_public])
        end

        camera.name = name if name
        camera.owner = User.by_login(username) if username
        camera.is_public = inputs[:is_public] if privacy_changed
        camera.is_online = inputs[:is_online] unless inputs[:is_online].nil?

        [:jpg, :mjpg, :h264, :audio, :mpeg].each do |resource|
          url_name = "#{resource}_url"
          unless inputs[url_name].nil?
            unless inputs[url_name].empty?
              inputs[url_name].prepend('/') if inputs[url_name][0,1] != '/'
            end
            if camera.values[:config].has_key?('snapshots')
              camera.values[:config]['snapshots'].merge!({resource => inputs[url_name]})
            else
              camera.values[:config].merge!({'snapshots' => { resource => inputs[url_name]}})
            end
          end
        end

        if inputs[:cam_username] or inputs[:cam_password]
          camera.values[:config].merge!({'auth' => {'basic' => {'username' => inputs[:cam_username].to_s.empty? ? '' : inputs[:cam_username],
                                                                'password' => inputs[:cam_password].to_s.empty? ? '' : inputs[:cam_password]}}})
        end

        camera.timezone = timezone if timezone
        # Update or reset vendor model
        camera.vendor_model =  VendorModel.find(:exid => model, :vendor_id => Vendor.find(:exid => vendor).id) unless model.blank?
        camera.vendor_model = nil if not model.nil? and model.empty?

        unless inputs[:mac_address].nil?
          camera.mac_address = inputs[:mac_address].empty? ? nil : mac_address
        end

        # setup camera GPS location
        unless location_lng.blank? && location_lat.blank?
          begin
            camera.location = { lng: location_lng.to_f, lat: location_lat.to_f }
          rescue ArgumentError
{'fraction_non_alphanumeric': 0.11997201818817768, 'fraction_numerical': 0.003322840153899965, 'mean_word_length': 2.3461088355763606, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4863364', 'n_tokens_mistral': 3301, 'n_tokens_neox': 3233, 'n_words': 810}