Documentation
¶
Index ¶
- Constants
- Variables
- func CalcPriceMinMaxRangeSeries(flats []Flat, origFlat Flat) (PriceHistoryWithOptions, PriceHistoryWithOptions)
- func FileExists(filename string) bool
- func FileExistsNonBlocking(filename string) bool
- func FileNotUpdated(filename string) bool
- func FilterWithFlatStorage(msg *MessageData) ([]string, error)
- func FilterWithFlatStorageHelper(oldMsg, newMsg *MessageData) []string
- func GetFinishTypeString(finishType int8) string
- func GetSettlementQuarter(settlementDate string) string
- func GetStorageFileName(msg *MessageData) string
- func GetStorageFileNameByBlockSlug(blockSlug string) string
- func GetStorageFileNameByBlockSlugAndEnv(blockSlug string) string
- func GetStorageFileNameByEnv(msg *MessageData) string
- func IsAreaSimilarForMaxPrice(origArea, anotherArea float64) bool
- func IsAreaSimilarForMinPrice(origArea, anotherArea float64) bool
- func UpdateFlatStorage(msg *MessageData) (numUpdated int, err error)
- type AveragePriceAggregator
- type AveragePriceKey
- type Body
- type Data
- type Flat
- func (f *Flat) GetPriceBelowAveragePercentage() float64
- func (f *Flat) GetPriceDropPercentage() float64
- func (f *Flat) GetPriceHistory() PriceHistory
- func (f *Flat) IsSimilar(another Flat) bool
- func (f *Flat) PercentageDropString() string
- func (f *Flat) RecentlyUpdated(now time.Time) bool
- func (f *Flat) String() string
- func (f *Flat) StringWithOptions() string
- type FlatStats
- type MessageData
- func (md *MessageData) CalcAveragePrices()
- func (md *MessageData) Copy() *MessageData
- func (md *MessageData) GetBlockSlug() string
- func (md *MessageData) GetInfoToSend(stats FlatStats) (string, []byte)
- func (md *MessageData) MakeHeader() string
- func (md *MessageData) String() string
- func (md *MessageData) StringWithOptions(sortByAvg bool, withInfo bool) string
- type Metro
- type PriceDropMessageData
- type PriceEntry
- type PriceEntryOption
- type PriceHistory
- type PriceHistoryWithOptions
- type Stats
Constants ¶
const ( FileMaxUpdatePeriod = 30 * time.Minute DefaultBelowAverageThreshold = 10 DefaultPriceDropPercentThreshold = 15 DefaultExtremePriceDropPercentThreshold = 30 )
const ( FlatValidInterval = 60 * time.Minute PriceComparisonInterval = 7 * 24 * time.Hour SimilarAreaThresholdPercentFrom = 5 SimilarAreaThresholdPercentTo = 5 PercentageChangeEpsilon = 0.05 )
Variables ¶
var FileMutex sync.RWMutex
Functions ¶
func CalcPriceMinMaxRangeSeries ¶
func CalcPriceMinMaxRangeSeries(flats []Flat, origFlat Flat) (PriceHistoryWithOptions, PriceHistoryWithOptions)
func FileExists ¶
func FileExistsNonBlocking ¶
func FileNotUpdated ¶
func FilterWithFlatStorage ¶
func FilterWithFlatStorage(msg *MessageData) ([]string, error)
FilterWithFlatStorage filter through local file (MVP)
func FilterWithFlatStorageHelper ¶
func FilterWithFlatStorageHelper(oldMsg, newMsg *MessageData) []string
func GetFinishTypeString ¶
func GetSettlementQuarter ¶
ex 2025-06-15 => 25Q3
func GetStorageFileName ¶
func GetStorageFileName(msg *MessageData) string
func GetStorageFileNameByEnv ¶
func GetStorageFileNameByEnv(msg *MessageData) string
func IsAreaSimilarForMaxPrice ¶
IsAreaSimilarForMaxPrice checks that another area is eligible to be in max price window (-20%, +2%)
func IsAreaSimilarForMinPrice ¶
IsAreaSimilarForMinPrice checks that another area is eligible to be in min price window (-2%, +20%)
func UpdateFlatStorage ¶
func UpdateFlatStorage(msg *MessageData) (numUpdated int, err error)
UpdateFlatStorage update local file (MVP)
Types ¶
type AveragePriceAggregator ¶
type AveragePriceAggregator map[AveragePriceKey][]int
type AveragePriceKey ¶
type Flat ¶
type Flat struct {
ID int64 `json:"id"`
Area float64 `json:"area"`
Floor int64 `json:"floor"`
Metro Metro `json:"metro"`
Price int64 `json:"price"` // in rub
Rooms int8 `json:"rooms"`
Status string `json:"status"`
// TODO: find Url plan with areas, maybe with address https://www.pik.ru/flat/819556
// https://flat.pik-service.ru/api/v1/flat/819556
PlanURL string `json:"planUrl"` // https:\/\/0.db-estate.cdn.pik-service.ru\/layout\/2022\/06\/13\/1_sem2_2el36_4_2x12_6-1_t_a_90_PgbXHE4ZDppCmmc2.svg
BulkName string `json:"bulkName"` // Корпус 1.1
MaxFloor int8 `json:"maxFloor"` // 33
BlockName string `json:"blockName"` // Второй Нагатинский
BlockSlug string `json:"blockSlug"`
Created string `json:"created,omitempty"` // when the flat first appeared
Updated string `json:"updated,omitempty"` // when the flat was last seen (to filter out the old ones)
FinishType int8 `json:"finishType"`
SettlementDate string `json:"settlementDate"`
AveragePrice int64 `json:"averagePrice"`
OldPrice int64 `json:"oldPrice"`
PriceHistory PriceHistory `json:"priceHistory,omitempty"`
}
url example: https://flat.pik-service.ru/api/v1/filter/flat-by-block/1240?type=1,2&location=2,3&flatLimit=80&onlyFlats=1 source example: {"id":830713,"area":65.2,"floor":17,"metro":{"id":148, "name":"\u041d\u0430\u0433\u0430\u0442\u0438\u043d\u0441\u043a\u0430\u044f","color":"#ACADAF"}, "price":21796360,"rooms":2,"status":"free","typeId":1, "planUrl":"https:\/\/0.db-estate.cdn.pik-service.ru\/layout\/2022\/06\/13\/1_sem2_2el36_4_2x12_6-1_t_a_90_PgbXHE4ZDppCmmc2.svg", "bulkName":"\u041a\u043e\u0440\u043f\u0443\u0441 1.1","maxFloor":33, "blockName":"\u0412\u0442\u043e\u0440\u043e\u0439 \u041d\u0430\u0433\u0430\u0442\u0438\u043d\u0441\u043a\u0438\u0439", "blockSlug":"2ngt","finishType":1,"meterPrice":334300,"settlementDate":"2025-06-15","currentBenefitId":114464}
func (*Flat) GetPriceBelowAveragePercentage ¶
func (*Flat) GetPriceDropPercentage ¶
func (*Flat) GetPriceHistory ¶
func (f *Flat) GetPriceHistory() PriceHistory
func (*Flat) PercentageDropString ¶
func (*Flat) String ¶
String example: Корпус 1.3 #831859[url link to flat]: 32.6m, 1r, f19, 12_756_380rub,
func (*Flat) StringWithOptions ¶
type MessageData ¶
func MergeNewFlatsIntoOld ¶
func MergeNewFlatsIntoOld(oldMsg, newMsg *MessageData) *MessageData
func ReadFlatStorage ¶
func ReadFlatStorage(fileName string) (*MessageData, error)
func UnmarshallFlats ¶
func UnmarshallFlats(body []byte) (*MessageData, error)
func (*MessageData) CalcAveragePrices ¶
func (md *MessageData) CalcAveragePrices()
func (*MessageData) Copy ¶
func (md *MessageData) Copy() *MessageData
func (*MessageData) GetBlockSlug ¶
func (md *MessageData) GetBlockSlug() string
func (*MessageData) GetInfoToSend ¶
func (md *MessageData) GetInfoToSend(stats FlatStats) (string, []byte)
func (*MessageData) MakeHeader ¶
func (md *MessageData) MakeHeader() string
MakeHeader example: // {number of Flats} новых объектов в ЖК "Второй Нагатинский" (м.Нагатинская (color #ACADAF)):
func (*MessageData) String ¶
func (md *MessageData) String() string
String print in human readable telegram friendly format example input: {831859 32.6 19 {Нагатинская #ACADAF} 12756380 1 free https://0.db-estate.cdn.pik-service.ru/attachment/0/167b4389-02d9-eb11-84e9-02bf0a4d8e27/6_sem2_1es3_5.7-1_s_z_07ef74f33ec511c288fe633c87ef297c.svg Корпус 1.3 33 Второй Нагатинский} example output: {number of Flats} новых объектов в ЖК "Второй Нагатинский" (м.Нагатинская (color #ACADAF)): Корпус 1.3 #831859[url link to flat]: 32.6m, 1r, f19, 12_756_380rub,
func (*MessageData) StringWithOptions ¶
func (md *MessageData) StringWithOptions(sortByAvg bool, withInfo bool) string
type PriceDropMessageData ¶
func (*PriceDropMessageData) MakeHeader ¶
func (md *PriceDropMessageData) MakeHeader(prompt string) string
MakeHeader example: {number of Flats} квартир подешевели более, чем на {price_drop_threshold}% в ЖК "Второй Нагатинский":
func (*PriceDropMessageData) String ¶
func (md *PriceDropMessageData) String() string
String print in human readable telegram friendly format example input: {831859 32.6 19 {Нагатинская #ACADAF} 12756380 1 free https://0.db-estate.cdn.pik-service.ru/attachment/0/167b4389-02d9-eb11-84e9-02bf0a4d8e27/6_sem2_1es3_5.7-1_s_z_07ef74f33ec511c288fe633c87ef297c.svg Корпус 1.3 33 Второй Нагатинский} example output: {number of Flats} квартир подешевели более, чем на {price_drop_threshold}% в ЖК "Второй Нагатинский": Корпус 1.3 #831859[url link to flat]: 32.6m, 1r, f19, 12_756_380rub, {(price_new/price_old - 1)*100)%
func (*PriceDropMessageData) StringWithPrompt ¶
func (md *PriceDropMessageData) StringWithPrompt(prompt string) string
type PriceEntry ¶
type PriceEntryOption ¶
type PriceEntryOption struct {
PriceEntry
Area float64
Status string
}
type PriceHistory ¶
type PriceHistory []PriceEntry
type PriceHistoryWithOptions ¶
type PriceHistoryWithOptions []PriceEntryOption